00001 /* Map logical line numbers to (source file, line number) pairs. 00002 Copyright (C) 2001, 2003, 2004 00003 Free Software Foundation, Inc. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of the GNU General Public License as published by the 00007 Free Software Foundation; either version 2, or (at your option) any 00008 later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 00019 In other words, you are welcome to use, share and improve this program. 00020 You are forbidden to forbid anyone else to use, share and improve 00021 what you give them. Help stamp out software-hoarding! */ 00022 00023 #ifndef LIBCPP_LINE_MAP_H 00024 #define LIBCPP_LINE_MAP_H 00025 00026 /* Reason for adding a line change with add_line_map (). LC_ENTER is 00027 when including a new file, e.g. a #include directive in C. 00028 LC_LEAVE is when reaching a file's end. LC_RENAME is when a file 00029 name or line number changes for neither of the above reasons 00030 (e.g. a #line directive in C). */ 00031 enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME}; 00032 00033 /* A logical line/column number, i.e. an "index" into a line_map. */ 00034 /* Long-term, we want to use this to replace struct location_s (in input.h), 00035 and effectively typedef source_location location_t. */ 00036 typedef unsigned int source_location; 00037 00038 /* Physical source file TO_FILE at line TO_LINE at column 0 is represented 00039 by the logical START_LOCATION. TO_LINE+L at column C is represented by 00040 START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits), 00041 and the result_location is less than the next line_map's start_location. 00042 (The top line is line 1 and the leftmost column is column 1; line/column 0 00043 means "entire file/line" or "unknown line/column" or "not applicable".) 00044 INCLUDED_FROM is an index into the set that gives the line mapping 00045 at whose end the current one was included. File(s) at the bottom 00046 of the include stack have this set to -1. REASON is the reason for 00047 creation of this line map, SYSP is one for a system header, two for 00048 a C system header file that therefore needs to be extern "C" 00049 protected in C++, and zero otherwise. */ 00050 struct line_map 00051 { 00052 const char *to_file; 00053 unsigned int to_line; 00054 source_location start_location; 00055 int included_from; 00056 ENUM_BITFIELD (lc_reason) reason : CHAR_BIT; 00057 /* The sysp field isn't really needed now that it's in cpp_buffer. */ 00058 unsigned char sysp; 00059 /* Number of the low-order source_location bits used for a column number. */ 00060 unsigned int column_bits : 8; 00061 }; 00062 00063 /* A set of chronological line_map structures. */ 00064 struct line_maps 00065 { 00066 struct line_map *maps; 00067 unsigned int allocated; 00068 unsigned int used; 00069 00070 unsigned int cache; 00071 00072 /* The most recently listed include stack, if any, starts with 00073 LAST_LISTED as the topmost including file. -1 indicates nothing 00074 has been listed yet. */ 00075 int last_listed; 00076 00077 /* Depth of the include stack, including the current file. */ 00078 unsigned int depth; 00079 00080 /* If true, prints an include trace a la -H. */ 00081 bool trace_includes; 00082 00083 /* Highest source_location "given out". */ 00084 source_location highest_location; 00085 00086 /* Start of line of highest source_location "given out". */ 00087 source_location highest_line; 00088 00089 /* The maximum column number we can quickly allocate. Higher numbers 00090 may require allocating a new line_map. */ 00091 unsigned int max_column_hint; 00092 }; 00093 00094 /* Initialize a line map set. */ 00095 extern void linemap_init (struct line_maps *); 00096 00097 /* Free a line map set. */ 00098 extern void linemap_free (struct line_maps *); 00099 00100 /* Check for and warn about line_maps entered but not exited. */ 00101 00102 extern void linemap_check_files_exited (struct line_maps *); 00103 00104 /* Return a source_location for the start (i.e. column==0) of 00105 (physical) line TO_LINE in the current source file (as in the 00106 most recent linemap_add). MAX_COLUMN_HINT is the highest column 00107 number we expect to use in this line (but it does not change 00108 the highest_location). */ 00109 00110 extern source_location linemap_line_start 00111 (struct line_maps *set, unsigned int to_line, unsigned int max_column_hint); 00112 00113 /* Add a mapping of logical source line to physical source file and 00114 line number. 00115 00116 The text pointed to by TO_FILE must have a lifetime 00117 at least as long as the final call to lookup_line (). An empty 00118 TO_FILE means standard input. If reason is LC_LEAVE, and 00119 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their 00120 natural values considering the file we are returning to. 00121 00122 A call to this function can relocate the previous set of 00123 maps, so any stored line_map pointers should not be used. */ 00124 extern const struct line_map *linemap_add 00125 (struct line_maps *, enum lc_reason, unsigned int sysp, 00126 const char *to_file, unsigned int to_line); 00127 00128 /* Given a logical line, returns the map from which the corresponding 00129 (source file, line) pair can be deduced. */ 00130 extern const struct line_map *linemap_lookup 00131 (struct line_maps *, source_location); 00132 00133 /* Print the file names and line numbers of the #include commands 00134 which led to the map MAP, if any, to stderr. Nothing is output if 00135 the most recently listed stack is the same as the current one. */ 00136 extern void linemap_print_containing_files (struct line_maps *, 00137 const struct line_map *); 00138 00139 /* Converts a map and a source_location to source line. */ 00140 #define SOURCE_LINE(MAP, LINE) \ 00141 ((((LINE) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line) 00142 00143 #define SOURCE_COLUMN(MAP, LINE) \ 00144 (((LINE) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1)) 00145 00146 /* Returns the last source line within a map. This is the (last) line 00147 of the #include, or other directive, that caused a map change. */ 00148 #define LAST_SOURCE_LINE(MAP) \ 00149 SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP)) 00150 #define LAST_SOURCE_LINE_LOCATION(MAP) \ 00151 ((((MAP)[1].start_location - 1 - (MAP)->start_location) \ 00152 & ~((1 << (MAP)->column_bits) - 1)) \ 00153 + (MAP)->start_location) 00154 00155 /* Returns the map a given map was included from. */ 00156 #define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from]) 00157 00158 /* Nonzero if the map is at the bottom of the include stack. */ 00159 #define MAIN_FILE_P(MAP) ((MAP)->included_from < 0) 00160 00161 /* Set LOC to a source position that is the same line as the most recent 00162 linemap_line_start, but with the specified TO_COLUMN column number. */ 00163 00164 #define LINEMAP_POSITION_FOR_COLUMN(LOC, SET, TO_COLUMN) { \ 00165 unsigned int to_column = (TO_COLUMN); \ 00166 struct line_maps *set = (SET); \ 00167 if (__builtin_expect (to_column >= set->max_column_hint, 0)) \ 00168 (LOC) = linemap_position_for_column (set, to_column); \ 00169 else { \ 00170 source_location r = set->highest_line; \ 00171 r = r + to_column; \ 00172 if (r >= set->highest_location) \ 00173 set->highest_location = r; \ 00174 (LOC) = r; \ 00175 }} 00176 00177 00178 extern source_location 00179 linemap_position_for_column (struct line_maps *set, unsigned int to_column); 00180 #endif /* !LIBCPP_LINE_MAP_H */
1.5.6