| 1 | 730 | jeremybenn | /* Map logical line numbers to (source file, line number) pairs.
 | 
      
         | 2 |  |  |    Copyright (C) 2001, 2003, 2004, 2007, 2008, 2009, 2010, 2011
 | 
      
         | 3 |  |  |    Free Software Foundation, Inc.
 | 
      
         | 4 |  |  |  
 | 
      
         | 5 |  |  | This program is free software; you can redistribute it and/or modify it
 | 
      
         | 6 |  |  | under the terms of the GNU General Public License as published by the
 | 
      
         | 7 |  |  | Free Software Foundation; either version 3, or (at your option) any
 | 
      
         | 8 |  |  | later version.
 | 
      
         | 9 |  |  |  
 | 
      
         | 10 |  |  | This program is distributed in the hope that it will be useful,
 | 
      
         | 11 |  |  | but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
      
         | 12 |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
      
         | 13 |  |  | GNU General Public License for more details.
 | 
      
         | 14 |  |  |  
 | 
      
         | 15 |  |  | You should have received a copy of the GNU General Public License
 | 
      
         | 16 |  |  | along with this program; see the file COPYING3.  If not see
 | 
      
         | 17 |  |  | <http://www.gnu.org/licenses/>.
 | 
      
         | 18 |  |  |  
 | 
      
         | 19 |  |  |  In other words, you are welcome to use, share and improve this program.
 | 
      
         | 20 |  |  |  You are forbidden to forbid anyone else to use, share and improve
 | 
      
         | 21 |  |  |  what you give them.   Help stamp out software-hoarding!  */
 | 
      
         | 22 |  |  |  
 | 
      
         | 23 |  |  | #include "config.h"
 | 
      
         | 24 |  |  | #include "system.h"
 | 
      
         | 25 |  |  | #include "line-map.h"
 | 
      
         | 26 |  |  | #include "cpplib.h"
 | 
      
         | 27 |  |  | #include "internal.h"
 | 
      
         | 28 |  |  |  
 | 
      
         | 29 |  |  | static void trace_include (const struct line_maps *, const struct line_map *);
 | 
      
         | 30 |  |  | static const struct line_map * linemap_ordinary_map_lookup (struct line_maps *,
 | 
      
         | 31 |  |  |                                                             source_location);
 | 
      
         | 32 |  |  | static const struct line_map* linemap_macro_map_lookup (struct line_maps *,
 | 
      
         | 33 |  |  |                                                         source_location);
 | 
      
         | 34 |  |  | static source_location linemap_macro_map_loc_to_def_point
 | 
      
         | 35 |  |  | (const struct line_map*, source_location);
 | 
      
         | 36 |  |  | static source_location linemap_macro_map_loc_unwind_toward_spelling
 | 
      
         | 37 |  |  | (const struct line_map*, source_location);
 | 
      
         | 38 |  |  | static source_location linemap_macro_map_loc_to_exp_point
 | 
      
         | 39 |  |  | (const struct line_map*, source_location);
 | 
      
         | 40 |  |  | static source_location linemap_macro_loc_to_spelling_point
 | 
      
         | 41 |  |  | (struct line_maps *, source_location, const struct line_map **);
 | 
      
         | 42 |  |  | static source_location linemap_macro_loc_to_def_point (struct line_maps *,
 | 
      
         | 43 |  |  |                                                        source_location,
 | 
      
         | 44 |  |  |                                                        const struct line_map **);
 | 
      
         | 45 |  |  | static source_location linemap_macro_loc_to_exp_point (struct line_maps *,
 | 
      
         | 46 |  |  |                                                        source_location,
 | 
      
         | 47 |  |  |                                                        const struct line_map **);
 | 
      
         | 48 |  |  |  
 | 
      
         | 49 |  |  | /* Counters defined in macro.c.  */
 | 
      
         | 50 |  |  | extern unsigned num_expanded_macros_counter;
 | 
      
         | 51 |  |  | extern unsigned num_macro_tokens_counter;
 | 
      
         | 52 |  |  |  
 | 
      
         | 53 |  |  | /* Initialize a line map set.  */
 | 
      
         | 54 |  |  |  
 | 
      
         | 55 |  |  | void
 | 
      
         | 56 |  |  | linemap_init (struct line_maps *set)
 | 
      
         | 57 |  |  | {
 | 
      
         | 58 |  |  |   memset (set, 0, sizeof (struct line_maps));
 | 
      
         | 59 |  |  |   set->highest_location = RESERVED_LOCATION_COUNT - 1;
 | 
      
         | 60 |  |  |   set->highest_line = RESERVED_LOCATION_COUNT - 1;
 | 
      
         | 61 |  |  | }
 | 
      
         | 62 |  |  |  
 | 
      
         | 63 |  |  | /* Check for and warn about line_maps entered but not exited.  */
 | 
      
         | 64 |  |  |  
 | 
      
         | 65 |  |  | void
 | 
      
         | 66 |  |  | linemap_check_files_exited (struct line_maps *set)
 | 
      
         | 67 |  |  | {
 | 
      
         | 68 |  |  |   struct line_map *map;
 | 
      
         | 69 |  |  |   /* Depending upon whether we are handling preprocessed input or
 | 
      
         | 70 |  |  |      not, this can be a user error or an ICE.  */
 | 
      
         | 71 |  |  |   for (map = LINEMAPS_LAST_ORDINARY_MAP (set);
 | 
      
         | 72 |  |  |        ! MAIN_FILE_P (map);
 | 
      
         | 73 |  |  |        map = INCLUDED_FROM (set, map))
 | 
      
         | 74 |  |  |     fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
 | 
      
         | 75 |  |  |              ORDINARY_MAP_FILE_NAME (map));
 | 
      
         | 76 |  |  | }
 | 
      
         | 77 |  |  |  
 | 
      
         | 78 |  |  | /* Create a new line map in the line map set SET, and return it.
 | 
      
         | 79 |  |  |    REASON is the reason of creating the map. It determines the type
 | 
      
         | 80 |  |  |    of map created (ordinary or macro map). Note that ordinary maps and
 | 
      
         | 81 |  |  |    macro maps are allocated in different memory location.  */
 | 
      
         | 82 |  |  |  
 | 
      
         | 83 |  |  | static struct line_map *
 | 
      
         | 84 |  |  | new_linemap (struct line_maps *set,
 | 
      
         | 85 |  |  |              enum lc_reason reason)
 | 
      
         | 86 |  |  | {
 | 
      
         | 87 |  |  |   /* Depending on this variable, a macro map would be allocated in a
 | 
      
         | 88 |  |  |      different memory location than an ordinary map.  */
 | 
      
         | 89 |  |  |   bool macro_map_p = (reason == LC_ENTER_MACRO);
 | 
      
         | 90 |  |  |   struct line_map *result;
 | 
      
         | 91 |  |  |  
 | 
      
         | 92 |  |  |   if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p))
 | 
      
         | 93 |  |  |     {
 | 
      
         | 94 |  |  |       /* We ran out of allocated line maps. Let's allocate more.  */
 | 
      
         | 95 |  |  |       unsigned alloc_size;
 | 
      
         | 96 |  |  |  
 | 
      
         | 97 |  |  |       line_map_realloc reallocator
 | 
      
         | 98 |  |  |         = set->reallocator ? set->reallocator : xrealloc;
 | 
      
         | 99 |  |  |       line_map_round_alloc_size_func round_alloc_size =
 | 
      
         | 100 |  |  |         set->round_alloc_size;
 | 
      
         | 101 |  |  |  
 | 
      
         | 102 |  |  |       /* We are going to execute some dance to try to reduce the
 | 
      
         | 103 |  |  |          overhead of the memory allocator, in case we are using the
 | 
      
         | 104 |  |  |          ggc-page.c one.
 | 
      
         | 105 |  |  |  
 | 
      
         | 106 |  |  |          The actual size of memory we are going to get back from the
 | 
      
         | 107 |  |  |          allocator is the smallest power of 2 that is greater than the
 | 
      
         | 108 |  |  |          size we requested.  So let's consider that size then.  */
 | 
      
         | 109 |  |  |  
 | 
      
         | 110 |  |  |       alloc_size =
 | 
      
         | 111 |  |  |         (2 * LINEMAPS_ALLOCATED (set, macro_map_p) +  256)
 | 
      
         | 112 |  |  |         * sizeof (struct line_map);
 | 
      
         | 113 |  |  |  
 | 
      
         | 114 |  |  |       /* Get the actual size of memory that is going to be allocated
 | 
      
         | 115 |  |  |          by the allocator.  */
 | 
      
         | 116 |  |  |       alloc_size = round_alloc_size (alloc_size);
 | 
      
         | 117 |  |  |  
 | 
      
         | 118 |  |  |       /* Now alloc_size contains the exact memory size we would get if
 | 
      
         | 119 |  |  |          we have asked for the initial alloc_size amount of memory.
 | 
      
         | 120 |  |  |          Let's get back to the number of macro map that amounts
 | 
      
         | 121 |  |  |          to.  */
 | 
      
         | 122 |  |  |       LINEMAPS_ALLOCATED (set, macro_map_p) =
 | 
      
         | 123 |  |  |         alloc_size / (sizeof (struct line_map));
 | 
      
         | 124 |  |  |  
 | 
      
         | 125 |  |  |       /* And now let's really do the re-allocation.  */
 | 
      
         | 126 |  |  |       LINEMAPS_MAPS (set, macro_map_p) =
 | 
      
         | 127 |  |  |         (struct line_map *) (*reallocator)
 | 
      
         | 128 |  |  |         (LINEMAPS_MAPS (set, macro_map_p),
 | 
      
         | 129 |  |  |          (LINEMAPS_ALLOCATED (set, macro_map_p)
 | 
      
         | 130 |  |  |           * sizeof (struct line_map)));
 | 
      
         | 131 |  |  |  
 | 
      
         | 132 |  |  |       result =
 | 
      
         | 133 |  |  |         &LINEMAPS_MAPS (set, macro_map_p)[LINEMAPS_USED (set, macro_map_p)];
 | 
      
         | 134 |  |  |       memset (result, 0,
 | 
      
         | 135 |  |  |               ((LINEMAPS_ALLOCATED (set, macro_map_p)
 | 
      
         | 136 |  |  |                 - LINEMAPS_USED (set, macro_map_p))
 | 
      
         | 137 |  |  |                * sizeof (struct line_map)));
 | 
      
         | 138 |  |  |     }
 | 
      
         | 139 |  |  |   else
 | 
      
         | 140 |  |  |     result =
 | 
      
         | 141 |  |  |       &LINEMAPS_MAPS (set, macro_map_p)[LINEMAPS_USED (set, macro_map_p)];
 | 
      
         | 142 |  |  |  
 | 
      
         | 143 |  |  |   LINEMAPS_USED (set, macro_map_p)++;
 | 
      
         | 144 |  |  |  
 | 
      
         | 145 |  |  |   result->reason = reason;
 | 
      
         | 146 |  |  |   return result;
 | 
      
         | 147 |  |  | }
 | 
      
         | 148 |  |  |  
 | 
      
         | 149 |  |  | /* Add a mapping of logical source line to physical source file and
 | 
      
         | 150 |  |  |    line number.
 | 
      
         | 151 |  |  |  
 | 
      
         | 152 |  |  |    The text pointed to by TO_FILE must have a lifetime
 | 
      
         | 153 |  |  |    at least as long as the final call to lookup_line ().  An empty
 | 
      
         | 154 |  |  |    TO_FILE means standard input.  If reason is LC_LEAVE, and
 | 
      
         | 155 |  |  |    TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
 | 
      
         | 156 |  |  |    natural values considering the file we are returning to.
 | 
      
         | 157 |  |  |  
 | 
      
         | 158 |  |  |    FROM_LINE should be monotonic increasing across calls to this
 | 
      
         | 159 |  |  |    function.  A call to this function can relocate the previous set of
 | 
      
         | 160 |  |  |    maps, so any stored line_map pointers should not be used.  */
 | 
      
         | 161 |  |  |  
 | 
      
         | 162 |  |  | const struct line_map *
 | 
      
         | 163 |  |  | linemap_add (struct line_maps *set, enum lc_reason reason,
 | 
      
         | 164 |  |  |              unsigned int sysp, const char *to_file, linenum_type to_line)
 | 
      
         | 165 |  |  | {
 | 
      
         | 166 |  |  |   struct line_map *map;
 | 
      
         | 167 |  |  |   source_location start_location = set->highest_location + 1;
 | 
      
         | 168 |  |  |  
 | 
      
         | 169 |  |  |   linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
 | 
      
         | 170 |  |  |                     && (start_location
 | 
      
         | 171 |  |  |                         < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))));
 | 
      
         | 172 |  |  |  
 | 
      
         | 173 |  |  |   /* When we enter the file for the first time reason cannot be
 | 
      
         | 174 |  |  |      LC_RENAME.  */
 | 
      
         | 175 |  |  |   linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
 | 
      
         | 176 |  |  |  
 | 
      
         | 177 |  |  |   /* If we are leaving the main file, return a NULL map.  */
 | 
      
         | 178 |  |  |   if (reason == LC_LEAVE
 | 
      
         | 179 |  |  |       && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
 | 
      
         | 180 |  |  |       && to_file == NULL)
 | 
      
         | 181 |  |  |     {
 | 
      
         | 182 |  |  |       set->depth--;
 | 
      
         | 183 |  |  |       return NULL;
 | 
      
         | 184 |  |  |     }
 | 
      
         | 185 |  |  |  
 | 
      
         | 186 |  |  |   map = new_linemap (set, reason);
 | 
      
         | 187 |  |  |  
 | 
      
         | 188 |  |  |   if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
 | 
      
         | 189 |  |  |     to_file = "<stdin>";
 | 
      
         | 190 |  |  |  
 | 
      
         | 191 |  |  |   if (reason == LC_RENAME_VERBATIM)
 | 
      
         | 192 |  |  |     reason = LC_RENAME;
 | 
      
         | 193 |  |  |  
 | 
      
         | 194 |  |  |   if (reason == LC_LEAVE)
 | 
      
         | 195 |  |  |     {
 | 
      
         | 196 |  |  |       /* When we are just leaving an "included" file, and jump to the next
 | 
      
         | 197 |  |  |          location inside the "includer" right after the #include
 | 
      
         | 198 |  |  |          "included", this variable points the map in use right before the
 | 
      
         | 199 |  |  |          #include "included", inside the same "includer" file.  */
 | 
      
         | 200 |  |  |       struct line_map *from;
 | 
      
         | 201 |  |  |       bool error;
 | 
      
         | 202 |  |  |  
 | 
      
         | 203 |  |  |       if (MAIN_FILE_P (map - 1))
 | 
      
         | 204 |  |  |         {
 | 
      
         | 205 |  |  |           /* So this _should_ means we are leaving the main file --
 | 
      
         | 206 |  |  |              effectively ending the compilation unit. But to_file not
 | 
      
         | 207 |  |  |              being NULL means the caller thinks we are leaving to
 | 
      
         | 208 |  |  |              another file. This is an erroneous behaviour but we'll
 | 
      
         | 209 |  |  |              try to recover from it. Let's pretend we are not leaving
 | 
      
         | 210 |  |  |              the main file.  */
 | 
      
         | 211 |  |  |           error = true;
 | 
      
         | 212 |  |  |           reason = LC_RENAME;
 | 
      
         | 213 |  |  |           from = map - 1;
 | 
      
         | 214 |  |  |         }
 | 
      
         | 215 |  |  |       else
 | 
      
         | 216 |  |  |         {
 | 
      
         | 217 |  |  |           /* (MAP - 1) points to the map we are leaving. The
 | 
      
         | 218 |  |  |              map from which (MAP - 1) got included should be the map
 | 
      
         | 219 |  |  |              that comes right before MAP in the same file.  */
 | 
      
         | 220 |  |  |           from = INCLUDED_FROM (set, map - 1);
 | 
      
         | 221 |  |  |           error = to_file && filename_cmp (ORDINARY_MAP_FILE_NAME (from),
 | 
      
         | 222 |  |  |                                            to_file);
 | 
      
         | 223 |  |  |         }
 | 
      
         | 224 |  |  |  
 | 
      
         | 225 |  |  |       /* Depending upon whether we are handling preprocessed input or
 | 
      
         | 226 |  |  |          not, this can be a user error or an ICE.  */
 | 
      
         | 227 |  |  |       if (error)
 | 
      
         | 228 |  |  |         fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
 | 
      
         | 229 |  |  |                  to_file);
 | 
      
         | 230 |  |  |  
 | 
      
         | 231 |  |  |       /* A TO_FILE of NULL is special - we use the natural values.  */
 | 
      
         | 232 |  |  |       if (error || to_file == NULL)
 | 
      
         | 233 |  |  |         {
 | 
      
         | 234 |  |  |           to_file = ORDINARY_MAP_FILE_NAME (from);
 | 
      
         | 235 |  |  |           to_line = SOURCE_LINE (from, from[1].start_location);
 | 
      
         | 236 |  |  |           sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
 | 
      
         | 237 |  |  |         }
 | 
      
         | 238 |  |  |     }
 | 
      
         | 239 |  |  |  
 | 
      
         | 240 |  |  |   linemap_assert (reason != LC_ENTER_MACRO);
 | 
      
         | 241 |  |  |   ORDINARY_MAP_IN_SYSTEM_HEADER_P (map) = sysp;
 | 
      
         | 242 |  |  |   MAP_START_LOCATION (map) = start_location;
 | 
      
         | 243 |  |  |   ORDINARY_MAP_FILE_NAME (map) = to_file;
 | 
      
         | 244 |  |  |   ORDINARY_MAP_STARTING_LINE_NUMBER (map) = to_line;
 | 
      
         | 245 |  |  |   LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
 | 
      
         | 246 |  |  |   ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) = 0;
 | 
      
         | 247 |  |  |   set->highest_location = start_location;
 | 
      
         | 248 |  |  |   set->highest_line = start_location;
 | 
      
         | 249 |  |  |   set->max_column_hint = 0;
 | 
      
         | 250 |  |  |  
 | 
      
         | 251 |  |  |   if (reason == LC_ENTER)
 | 
      
         | 252 |  |  |     {
 | 
      
         | 253 |  |  |       ORDINARY_MAP_INCLUDER_FILE_INDEX (map) =
 | 
      
         | 254 |  |  |         set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2);
 | 
      
         | 255 |  |  |       set->depth++;
 | 
      
         | 256 |  |  |       if (set->trace_includes)
 | 
      
         | 257 |  |  |         trace_include (set, map);
 | 
      
         | 258 |  |  |     }
 | 
      
         | 259 |  |  |   else if (reason == LC_RENAME)
 | 
      
         | 260 |  |  |     ORDINARY_MAP_INCLUDER_FILE_INDEX (map) =
 | 
      
         | 261 |  |  |       ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]);
 | 
      
         | 262 |  |  |   else if (reason == LC_LEAVE)
 | 
      
         | 263 |  |  |     {
 | 
      
         | 264 |  |  |       set->depth--;
 | 
      
         | 265 |  |  |       ORDINARY_MAP_INCLUDER_FILE_INDEX (map) =
 | 
      
         | 266 |  |  |         ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1));
 | 
      
         | 267 |  |  |     }
 | 
      
         | 268 |  |  |  
 | 
      
         | 269 |  |  |   return map;
 | 
      
         | 270 |  |  | }
 | 
      
         | 271 |  |  |  
 | 
      
         | 272 |  |  | /* Returns TRUE if the line table set tracks token locations accross
 | 
      
         | 273 |  |  |    macro expansion, FALSE otherwise.  */
 | 
      
         | 274 |  |  |  
 | 
      
         | 275 |  |  | bool
 | 
      
         | 276 |  |  | linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
 | 
      
         | 277 |  |  | {
 | 
      
         | 278 |  |  |   return LINEMAPS_MACRO_MAPS (set) != NULL;
 | 
      
         | 279 |  |  | }
 | 
      
         | 280 |  |  |  
 | 
      
         | 281 |  |  | /* Create a macro map.  A macro map encodes source locations of tokens
 | 
      
         | 282 |  |  |    that are part of a macro replacement-list, at a macro expansion
 | 
      
         | 283 |  |  |    point.  See the extensive comments of struct line_map and struct
 | 
      
         | 284 |  |  |    line_map_macro, in line-map.h.
 | 
      
         | 285 |  |  |  
 | 
      
         | 286 |  |  |    This map shall be created when the macro is expanded.  The map
 | 
      
         | 287 |  |  |    encodes the source location of the expansion point of the macro as
 | 
      
         | 288 |  |  |    well as the "original" source location of each token that is part
 | 
      
         | 289 |  |  |    of the macro replacement-list.  If a macro is defined but never
 | 
      
         | 290 |  |  |    expanded, it has no macro map.  SET is the set of maps the macro
 | 
      
         | 291 |  |  |    map should be part of.  MACRO_NODE is the macro which the new macro
 | 
      
         | 292 |  |  |    map should encode source locations for.  EXPANSION is the location
 | 
      
         | 293 |  |  |    of the expansion point of MACRO. For function-like macros
 | 
      
         | 294 |  |  |    invocations, it's best to make it point to the closing parenthesis
 | 
      
         | 295 |  |  |    of the macro, rather than the the location of the first character
 | 
      
         | 296 |  |  |    of the macro.  NUM_TOKENS is the number of tokens that are part of
 | 
      
         | 297 |  |  |    the replacement-list of MACRO.
 | 
      
         | 298 |  |  |  
 | 
      
         | 299 |  |  |    Note that when we run out of the integer space available for source
 | 
      
         | 300 |  |  |    locations, this function returns NULL.  In that case, callers of
 | 
      
         | 301 |  |  |    this function cannot encode {line,column} pairs into locations of
 | 
      
         | 302 |  |  |    macro tokens anymore.  */
 | 
      
         | 303 |  |  |  
 | 
      
         | 304 |  |  | const struct line_map *
 | 
      
         | 305 |  |  | linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
 | 
      
         | 306 |  |  |                      source_location expansion, unsigned int num_tokens)
 | 
      
         | 307 |  |  | {
 | 
      
         | 308 |  |  |   struct line_map *map;
 | 
      
         | 309 |  |  |   source_location start_location;
 | 
      
         | 310 |  |  |   line_map_realloc reallocator
 | 
      
         | 311 |  |  |     = set->reallocator ? set->reallocator : xrealloc;
 | 
      
         | 312 |  |  |  
 | 
      
         | 313 |  |  |   start_location = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
 | 
      
         | 314 |  |  |  
 | 
      
         | 315 |  |  |   if (start_location <= set->highest_line
 | 
      
         | 316 |  |  |       || start_location > LINEMAPS_MACRO_LOWEST_LOCATION (set))
 | 
      
         | 317 |  |  |     /* We ran out of macro map space.   */
 | 
      
         | 318 |  |  |     return NULL;
 | 
      
         | 319 |  |  |  
 | 
      
         | 320 |  |  |   map = new_linemap (set, LC_ENTER_MACRO);
 | 
      
         | 321 |  |  |  
 | 
      
         | 322 |  |  |   MAP_START_LOCATION (map) = start_location;
 | 
      
         | 323 |  |  |   MACRO_MAP_MACRO (map) = macro_node;
 | 
      
         | 324 |  |  |   MACRO_MAP_NUM_MACRO_TOKENS (map) = num_tokens;
 | 
      
         | 325 |  |  |   MACRO_MAP_LOCATIONS (map)
 | 
      
         | 326 |  |  |     = (source_location*) reallocator (NULL,
 | 
      
         | 327 |  |  |                                       2 * num_tokens
 | 
      
         | 328 |  |  |                                       * sizeof (source_location));
 | 
      
         | 329 |  |  |   MACRO_MAP_EXPANSION_POINT_LOCATION (map) = expansion;
 | 
      
         | 330 |  |  |   memset (MACRO_MAP_LOCATIONS (map), 0,
 | 
      
         | 331 |  |  |           num_tokens * sizeof (source_location));
 | 
      
         | 332 |  |  |  
 | 
      
         | 333 |  |  |   LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
 | 
      
         | 334 |  |  |   set->max_column_hint = 0;
 | 
      
         | 335 |  |  |  
 | 
      
         | 336 |  |  |   return map;
 | 
      
         | 337 |  |  | }
 | 
      
         | 338 |  |  |  
 | 
      
         | 339 |  |  | /* Create and return a virtual location for a token that is part of a
 | 
      
         | 340 |  |  |    macro expansion-list at a macro expansion point.  See the comment
 | 
      
         | 341 |  |  |    inside struct line_map_macro to see what an expansion-list exactly
 | 
      
         | 342 |  |  |    is.
 | 
      
         | 343 |  |  |  
 | 
      
         | 344 |  |  |    A call to this function must come after a call to
 | 
      
         | 345 |  |  |    linemap_enter_macro.
 | 
      
         | 346 |  |  |  
 | 
      
         | 347 |  |  |    MAP is the map into which the source location is created.  TOKEN_NO
 | 
      
         | 348 |  |  |    is the index of the token in the macro replacement-list, starting
 | 
      
         | 349 |  |  |    at number 0.
 | 
      
         | 350 |  |  |  
 | 
      
         | 351 |  |  |    ORIG_LOC is the location of the token outside of this macro
 | 
      
         | 352 |  |  |    expansion.  If the token comes originally from the macro
 | 
      
         | 353 |  |  |    definition, it is the locus in the macro definition; otherwise it
 | 
      
         | 354 |  |  |    is a location in the context of the caller of this macro expansion
 | 
      
         | 355 |  |  |    (which is a virtual location or a source location if the caller is
 | 
      
         | 356 |  |  |    itself a macro expansion or not).
 | 
      
         | 357 |  |  |  
 | 
      
         | 358 |  |  |    MACRO_DEFINITION_LOC is the location in the macro definition,
 | 
      
         | 359 |  |  |    either of the token itself or of a macro parameter that it
 | 
      
         | 360 |  |  |    replaces.  */
 | 
      
         | 361 |  |  |  
 | 
      
         | 362 |  |  | source_location
 | 
      
         | 363 |  |  | linemap_add_macro_token (const struct line_map *map,
 | 
      
         | 364 |  |  |                          unsigned int token_no,
 | 
      
         | 365 |  |  |                          source_location orig_loc,
 | 
      
         | 366 |  |  |                          source_location orig_parm_replacement_loc)
 | 
      
         | 367 |  |  | {
 | 
      
         | 368 |  |  |   source_location result;
 | 
      
         | 369 |  |  |  
 | 
      
         | 370 |  |  |   linemap_assert (linemap_macro_expansion_map_p (map));
 | 
      
         | 371 |  |  |   linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
 | 
      
         | 372 |  |  |  
 | 
      
         | 373 |  |  |   MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
 | 
      
         | 374 |  |  |   MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
 | 
      
         | 375 |  |  |  
 | 
      
         | 376 |  |  |   result = MAP_START_LOCATION (map) + token_no;
 | 
      
         | 377 |  |  |   return result;
 | 
      
         | 378 |  |  | }
 | 
      
         | 379 |  |  |  
 | 
      
         | 380 |  |  | /* Return a source_location for the start (i.e. column==0) of
 | 
      
         | 381 |  |  |    (physical) line TO_LINE in the current source file (as in the
 | 
      
         | 382 |  |  |    most recent linemap_add).   MAX_COLUMN_HINT is the highest column
 | 
      
         | 383 |  |  |    number we expect to use in this line (but it does not change
 | 
      
         | 384 |  |  |    the highest_location).  */
 | 
      
         | 385 |  |  |  
 | 
      
         | 386 |  |  | source_location
 | 
      
         | 387 |  |  | linemap_line_start (struct line_maps *set, linenum_type to_line,
 | 
      
         | 388 |  |  |                     unsigned int max_column_hint)
 | 
      
         | 389 |  |  | {
 | 
      
         | 390 |  |  |   struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (set);
 | 
      
         | 391 |  |  |   source_location highest = set->highest_location;
 | 
      
         | 392 |  |  |   source_location r;
 | 
      
         | 393 |  |  |   linenum_type last_line =
 | 
      
         | 394 |  |  |     SOURCE_LINE (map, set->highest_line);
 | 
      
         | 395 |  |  |   int line_delta = to_line - last_line;
 | 
      
         | 396 |  |  |   bool add_map = false;
 | 
      
         | 397 |  |  |  
 | 
      
         | 398 |  |  |   if (line_delta < 0
 | 
      
         | 399 |  |  |       || (line_delta > 10
 | 
      
         | 400 |  |  |           && line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000)
 | 
      
         | 401 |  |  |       || (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)))
 | 
      
         | 402 |  |  |       || (max_column_hint <= 80
 | 
      
         | 403 |  |  |           && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10))
 | 
      
         | 404 |  |  |     {
 | 
      
         | 405 |  |  |       add_map = true;
 | 
      
         | 406 |  |  |     }
 | 
      
         | 407 |  |  |   else
 | 
      
         | 408 |  |  |     max_column_hint = set->max_column_hint;
 | 
      
         | 409 |  |  |   if (add_map)
 | 
      
         | 410 |  |  |     {
 | 
      
         | 411 |  |  |       int column_bits;
 | 
      
         | 412 |  |  |       if (max_column_hint > 100000 || highest > 0xC0000000)
 | 
      
         | 413 |  |  |         {
 | 
      
         | 414 |  |  |           /* If the column number is ridiculous or we've allocated a huge
 | 
      
         | 415 |  |  |              number of source_locations, give up on column numbers. */
 | 
      
         | 416 |  |  |           max_column_hint = 0;
 | 
      
         | 417 |  |  |           if (highest >0xF0000000)
 | 
      
         | 418 |  |  |             return 0;
 | 
      
         | 419 |  |  |           column_bits = 0;
 | 
      
         | 420 |  |  |         }
 | 
      
         | 421 |  |  |       else
 | 
      
         | 422 |  |  |         {
 | 
      
         | 423 |  |  |           column_bits = 7;
 | 
      
         | 424 |  |  |           while (max_column_hint >= (1U << column_bits))
 | 
      
         | 425 |  |  |             column_bits++;
 | 
      
         | 426 |  |  |           max_column_hint = 1U << column_bits;
 | 
      
         | 427 |  |  |         }
 | 
      
         | 428 |  |  |       /* Allocate the new line_map.  However, if the current map only has a
 | 
      
         | 429 |  |  |          single line we can sometimes just increase its column_bits instead. */
 | 
      
         | 430 |  |  |       if (line_delta < 0
 | 
      
         | 431 |  |  |           || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
 | 
      
         | 432 |  |  |           || SOURCE_COLUMN (map, highest) >= (1U << column_bits))
 | 
      
         | 433 |  |  |         map = (struct line_map *) linemap_add (set, LC_RENAME,
 | 
      
         | 434 |  |  |                                                ORDINARY_MAP_IN_SYSTEM_HEADER_P
 | 
      
         | 435 |  |  |                                                (map),
 | 
      
         | 436 |  |  |                                                ORDINARY_MAP_FILE_NAME (map),
 | 
      
         | 437 |  |  |                                                to_line);
 | 
      
         | 438 |  |  |       ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) = column_bits;
 | 
      
         | 439 |  |  |       r = (MAP_START_LOCATION (map)
 | 
      
         | 440 |  |  |            + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
 | 
      
         | 441 |  |  |               << column_bits));
 | 
      
         | 442 |  |  |     }
 | 
      
         | 443 |  |  |   else
 | 
      
         | 444 |  |  |     r = highest - SOURCE_COLUMN (map, highest)
 | 
      
         | 445 |  |  |       + (line_delta << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map));
 | 
      
         | 446 |  |  |  
 | 
      
         | 447 |  |  |   /* Locations of ordinary tokens are always lower than locations of
 | 
      
         | 448 |  |  |      macro tokens.  */
 | 
      
         | 449 |  |  |   if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
 | 
      
         | 450 |  |  |     return 0;
 | 
      
         | 451 |  |  |  
 | 
      
         | 452 |  |  |   set->highest_line = r;
 | 
      
         | 453 |  |  |   if (r > set->highest_location)
 | 
      
         | 454 |  |  |     set->highest_location = r;
 | 
      
         | 455 |  |  |   set->max_column_hint = max_column_hint;
 | 
      
         | 456 |  |  |   return r;
 | 
      
         | 457 |  |  | }
 | 
      
         | 458 |  |  |  
 | 
      
         | 459 |  |  | /* Encode and return a source_location from a column number. The
 | 
      
         | 460 |  |  |    source line considered is the last source line used to call
 | 
      
         | 461 |  |  |    linemap_line_start, i.e, the last source line which a location was
 | 
      
         | 462 |  |  |    encoded from.  */
 | 
      
         | 463 |  |  |  
 | 
      
         | 464 |  |  | source_location
 | 
      
         | 465 |  |  | linemap_position_for_column (struct line_maps *set, unsigned int to_column)
 | 
      
         | 466 |  |  | {
 | 
      
         | 467 |  |  |   source_location r = set->highest_line;
 | 
      
         | 468 |  |  |  
 | 
      
         | 469 |  |  |   linemap_assert
 | 
      
         | 470 |  |  |     (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
 | 
      
         | 471 |  |  |  
 | 
      
         | 472 |  |  |   if (to_column >= set->max_column_hint)
 | 
      
         | 473 |  |  |     {
 | 
      
         | 474 |  |  |       if (r >= 0xC000000 || to_column > 100000)
 | 
      
         | 475 |  |  |         {
 | 
      
         | 476 |  |  |           /* Running low on source_locations - disable column numbers.  */
 | 
      
         | 477 |  |  |           return r;
 | 
      
         | 478 |  |  |         }
 | 
      
         | 479 |  |  |       else
 | 
      
         | 480 |  |  |         {
 | 
      
         | 481 |  |  |           struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (set);
 | 
      
         | 482 |  |  |           r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
 | 
      
         | 483 |  |  |         }
 | 
      
         | 484 |  |  |     }
 | 
      
         | 485 |  |  |   r = r + to_column;
 | 
      
         | 486 |  |  |   if (r >= set->highest_location)
 | 
      
         | 487 |  |  |     set->highest_location = r;
 | 
      
         | 488 |  |  |   return r;
 | 
      
         | 489 |  |  | }
 | 
      
         | 490 |  |  |  
 | 
      
         | 491 |  |  | /* Encode and return a source location from a given line and
 | 
      
         | 492 |  |  |    column.  */
 | 
      
         | 493 |  |  |  
 | 
      
         | 494 |  |  | source_location
 | 
      
         | 495 |  |  | linemap_position_for_line_and_column (struct line_map *map,
 | 
      
         | 496 |  |  |                                       linenum_type line,
 | 
      
         | 497 |  |  |                                       unsigned column)
 | 
      
         | 498 |  |  | {
 | 
      
         | 499 |  |  |   linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (map) <= line);
 | 
      
         | 500 |  |  |  
 | 
      
         | 501 |  |  |   return (MAP_START_LOCATION (map)
 | 
      
         | 502 |  |  |           + ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
 | 
      
         | 503 |  |  |              << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map))
 | 
      
         | 504 |  |  |           + (column & ((1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)) - 1)));
 | 
      
         | 505 |  |  | }
 | 
      
         | 506 |  |  |  
 | 
      
         | 507 |  |  | /* Given a virtual source location yielded by a map (either an
 | 
      
         | 508 |  |  |    ordinary or a macro map), returns that map.  */
 | 
      
         | 509 |  |  |  
 | 
      
         | 510 |  |  | const struct line_map*
 | 
      
         | 511 |  |  | linemap_lookup (struct line_maps *set, source_location line)
 | 
      
         | 512 |  |  | {
 | 
      
         | 513 |  |  |   if (linemap_location_from_macro_expansion_p (set, line))
 | 
      
         | 514 |  |  |     return linemap_macro_map_lookup (set, line);
 | 
      
         | 515 |  |  |   return linemap_ordinary_map_lookup (set, line);
 | 
      
         | 516 |  |  | }
 | 
      
         | 517 |  |  |  
 | 
      
         | 518 |  |  | /* Given a source location yielded by an ordinary map, returns that
 | 
      
         | 519 |  |  |    map.  Since the set is built chronologically, the logical lines are
 | 
      
         | 520 |  |  |    monotonic increasing, and so the list is sorted and we can use a
 | 
      
         | 521 |  |  |    binary search.  */
 | 
      
         | 522 |  |  |  
 | 
      
         | 523 |  |  | static const struct line_map *
 | 
      
         | 524 |  |  | linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
 | 
      
         | 525 |  |  | {
 | 
      
         | 526 |  |  |   unsigned int md, mn, mx;
 | 
      
         | 527 |  |  |   const struct line_map *cached, *result;
 | 
      
         | 528 |  |  |  
 | 
      
         | 529 |  |  |   if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
 | 
      
         | 530 |  |  |     return NULL;
 | 
      
         | 531 |  |  |  
 | 
      
         | 532 |  |  |   mn = LINEMAPS_ORDINARY_CACHE (set);
 | 
      
         | 533 |  |  |   mx = LINEMAPS_ORDINARY_USED (set);
 | 
      
         | 534 |  |  |  
 | 
      
         | 535 |  |  |   cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
 | 
      
         | 536 |  |  |   /* We should get a segfault if no line_maps have been added yet.  */
 | 
      
         | 537 |  |  |   if (line >= MAP_START_LOCATION (cached))
 | 
      
         | 538 |  |  |     {
 | 
      
         | 539 |  |  |       if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
 | 
      
         | 540 |  |  |         return cached;
 | 
      
         | 541 |  |  |     }
 | 
      
         | 542 |  |  |   else
 | 
      
         | 543 |  |  |     {
 | 
      
         | 544 |  |  |       mx = mn;
 | 
      
         | 545 |  |  |       mn = 0;
 | 
      
         | 546 |  |  |     }
 | 
      
         | 547 |  |  |  
 | 
      
         | 548 |  |  |   while (mx - mn > 1)
 | 
      
         | 549 |  |  |     {
 | 
      
         | 550 |  |  |       md = (mn + mx) / 2;
 | 
      
         | 551 |  |  |       if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
 | 
      
         | 552 |  |  |         mx = md;
 | 
      
         | 553 |  |  |       else
 | 
      
         | 554 |  |  |         mn = md;
 | 
      
         | 555 |  |  |     }
 | 
      
         | 556 |  |  |  
 | 
      
         | 557 |  |  |   LINEMAPS_ORDINARY_CACHE (set) = mn;
 | 
      
         | 558 |  |  |   result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
 | 
      
         | 559 |  |  |   linemap_assert (line >= MAP_START_LOCATION (result));
 | 
      
         | 560 |  |  |   return result;
 | 
      
         | 561 |  |  | }
 | 
      
         | 562 |  |  |  
 | 
      
         | 563 |  |  | /* Given a source location yielded by a macro map, returns that map.
 | 
      
         | 564 |  |  |    Since the set is built chronologically, the logical lines are
 | 
      
         | 565 |  |  |    monotonic decreasing, and so the list is sorted and we can use a
 | 
      
         | 566 |  |  |    binary search.  */
 | 
      
         | 567 |  |  |  
 | 
      
         | 568 |  |  | static const struct line_map*
 | 
      
         | 569 |  |  | linemap_macro_map_lookup (struct line_maps *set, source_location line)
 | 
      
         | 570 |  |  | {
 | 
      
         | 571 |  |  |   unsigned int md, mn, mx;
 | 
      
         | 572 |  |  |   const struct line_map *cached, *result;
 | 
      
         | 573 |  |  |  
 | 
      
         | 574 |  |  |   linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
 | 
      
         | 575 |  |  |  
 | 
      
         | 576 |  |  |   if (set ==  NULL)
 | 
      
         | 577 |  |  |     return NULL;
 | 
      
         | 578 |  |  |  
 | 
      
         | 579 |  |  |   mn = LINEMAPS_MACRO_CACHE (set);
 | 
      
         | 580 |  |  |   mx = LINEMAPS_MACRO_USED (set);
 | 
      
         | 581 |  |  |   cached = LINEMAPS_MACRO_MAP_AT (set, mn);
 | 
      
         | 582 |  |  |  
 | 
      
         | 583 |  |  |   if (line >= MAP_START_LOCATION (cached))
 | 
      
         | 584 |  |  |     {
 | 
      
         | 585 |  |  |       if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
 | 
      
         | 586 |  |  |         return cached;
 | 
      
         | 587 |  |  |       mx = mn - 1;
 | 
      
         | 588 |  |  |       mn = 0;
 | 
      
         | 589 |  |  |     }
 | 
      
         | 590 |  |  |  
 | 
      
         | 591 |  |  |   while (mn < mx)
 | 
      
         | 592 |  |  |     {
 | 
      
         | 593 |  |  |       md = (mx + mn) / 2;
 | 
      
         | 594 |  |  |       if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
 | 
      
         | 595 |  |  |         mn = md + 1;
 | 
      
         | 596 |  |  |       else
 | 
      
         | 597 |  |  |         mx = md;
 | 
      
         | 598 |  |  |     }
 | 
      
         | 599 |  |  |  
 | 
      
         | 600 |  |  |   LINEMAPS_MACRO_CACHE (set) = mx;
 | 
      
         | 601 |  |  |   result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
 | 
      
         | 602 |  |  |   linemap_assert (MAP_START_LOCATION (result) <= line);
 | 
      
         | 603 |  |  |  
 | 
      
         | 604 |  |  |   return result;
 | 
      
         | 605 |  |  | }
 | 
      
         | 606 |  |  |  
 | 
      
         | 607 |  |  | /* Return TRUE if MAP encodes locations coming from a macro
 | 
      
         | 608 |  |  |    replacement-list at macro expansion point.  */
 | 
      
         | 609 |  |  |  
 | 
      
         | 610 |  |  | bool
 | 
      
         | 611 |  |  | linemap_macro_expansion_map_p (const struct line_map *map)
 | 
      
         | 612 |  |  | {
 | 
      
         | 613 |  |  |   if (!map)
 | 
      
         | 614 |  |  |     return false;
 | 
      
         | 615 |  |  |   return (map->reason == LC_ENTER_MACRO);
 | 
      
         | 616 |  |  | }
 | 
      
         | 617 |  |  |  
 | 
      
         | 618 |  |  | /* If LOCATION is the locus of a token in a replacement-list of a
 | 
      
         | 619 |  |  |    macro expansion return the location of the macro expansion point.
 | 
      
         | 620 |  |  |  
 | 
      
         | 621 |  |  |    Read the comments of struct line_map and struct line_map_macro in
 | 
      
         | 622 |  |  |    line-map.h to understand what a macro expansion point is.  */
 | 
      
         | 623 |  |  |  
 | 
      
         | 624 |  |  | static source_location
 | 
      
         | 625 |  |  | linemap_macro_map_loc_to_exp_point (const struct line_map *map,
 | 
      
         | 626 |  |  |                                     source_location location ATTRIBUTE_UNUSED)
 | 
      
         | 627 |  |  | {
 | 
      
         | 628 |  |  |   linemap_assert (linemap_macro_expansion_map_p (map)
 | 
      
         | 629 |  |  |                   && location >= MAP_START_LOCATION (map));
 | 
      
         | 630 |  |  |  
 | 
      
         | 631 |  |  |   /* Make sure LOCATION is correct.  */
 | 
      
         | 632 |  |  |   linemap_assert ((location - MAP_START_LOCATION (map))
 | 
      
         | 633 |  |  |                   <  MACRO_MAP_NUM_MACRO_TOKENS (map));
 | 
      
         | 634 |  |  |  
 | 
      
         | 635 |  |  |   return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
 | 
      
         | 636 |  |  | }
 | 
      
         | 637 |  |  |  
 | 
      
         | 638 |  |  | /* If LOCATION is the source location of a token that belongs to a
 | 
      
         | 639 |  |  |    macro replacement-list -- as part of a macro expansion -- then
 | 
      
         | 640 |  |  |    return the location of the token at the definition point of the
 | 
      
         | 641 |  |  |    macro.  Otherwise, return LOCATION.  SET is the set of maps
 | 
      
         | 642 |  |  |    location come from.  ORIGINAL_MAP is an output parm. If non NULL,
 | 
      
         | 643 |  |  |    the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
 | 
      
         | 644 |  |  |    returned location comes from.  */
 | 
      
         | 645 |  |  |  
 | 
      
         | 646 |  |  | source_location
 | 
      
         | 647 |  |  | linemap_macro_map_loc_to_def_point (const struct line_map *map,
 | 
      
         | 648 |  |  |                                     source_location location)
 | 
      
         | 649 |  |  | {
 | 
      
         | 650 |  |  |   unsigned token_no;
 | 
      
         | 651 |  |  |  
 | 
      
         | 652 |  |  |   linemap_assert (linemap_macro_expansion_map_p (map)
 | 
      
         | 653 |  |  |                   && location >= MAP_START_LOCATION (map));
 | 
      
         | 654 |  |  |   linemap_assert (location >= RESERVED_LOCATION_COUNT);
 | 
      
         | 655 |  |  |  
 | 
      
         | 656 |  |  |   token_no = location - MAP_START_LOCATION (map);
 | 
      
         | 657 |  |  |   linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
 | 
      
         | 658 |  |  |  
 | 
      
         | 659 |  |  |   location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
 | 
      
         | 660 |  |  |  
 | 
      
         | 661 |  |  |   return location;
 | 
      
         | 662 |  |  | }
 | 
      
         | 663 |  |  |  
 | 
      
         | 664 |  |  | /* If LOCATION is the locus of a token that is an argument of a
 | 
      
         | 665 |  |  |    function-like macro M and appears in the expansion of M, return the
 | 
      
         | 666 |  |  |    locus of that argument in the context of the caller of M.
 | 
      
         | 667 |  |  |  
 | 
      
         | 668 |  |  |    In other words, this returns the xI location presented in the
 | 
      
         | 669 |  |  |    comments of line_map_macro above.  */
 | 
      
         | 670 |  |  | source_location
 | 
      
         | 671 |  |  | linemap_macro_map_loc_unwind_toward_spelling (const struct line_map* map,
 | 
      
         | 672 |  |  |                                               source_location location)
 | 
      
         | 673 |  |  | {
 | 
      
         | 674 |  |  |   unsigned token_no;
 | 
      
         | 675 |  |  |  
 | 
      
         | 676 |  |  |   linemap_assert (linemap_macro_expansion_map_p (map)
 | 
      
         | 677 |  |  |                   && location >= MAP_START_LOCATION (map));
 | 
      
         | 678 |  |  |   linemap_assert (location >= RESERVED_LOCATION_COUNT);
 | 
      
         | 679 |  |  |  
 | 
      
         | 680 |  |  |   token_no = location - MAP_START_LOCATION (map);
 | 
      
         | 681 |  |  |   linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
 | 
      
         | 682 |  |  |  
 | 
      
         | 683 |  |  |   location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
 | 
      
         | 684 |  |  |  
 | 
      
         | 685 |  |  |   return location;
 | 
      
         | 686 |  |  | }
 | 
      
         | 687 |  |  |  
 | 
      
         | 688 |  |  | /* Return the source line number corresponding to source location
 | 
      
         | 689 |  |  |    LOCATION.  SET is the line map set LOCATION comes from.  If
 | 
      
         | 690 |  |  |    LOCATION is the source location of token that is part of the
 | 
      
         | 691 |  |  |    replacement-list of a macro expansion return the line number of the
 | 
      
         | 692 |  |  |    macro expansion point.  */
 | 
      
         | 693 |  |  |  
 | 
      
         | 694 |  |  | int
 | 
      
         | 695 |  |  | linemap_get_expansion_line (struct line_maps *set,
 | 
      
         | 696 |  |  |                             source_location location)
 | 
      
         | 697 |  |  | {
 | 
      
         | 698 |  |  |   const struct line_map *map = NULL;
 | 
      
         | 699 |  |  |  
 | 
      
         | 700 |  |  |   if (location < RESERVED_LOCATION_COUNT)
 | 
      
         | 701 |  |  |     return 0;
 | 
      
         | 702 |  |  |  
 | 
      
         | 703 |  |  |   location =
 | 
      
         | 704 |  |  |     linemap_macro_loc_to_exp_point (set, location, &map);
 | 
      
         | 705 |  |  |  
 | 
      
         | 706 |  |  |   return SOURCE_LINE (map, location);
 | 
      
         | 707 |  |  | }
 | 
      
         | 708 |  |  |  
 | 
      
         | 709 |  |  | /* Return the path of the file corresponding to source code location
 | 
      
         | 710 |  |  |    LOCATION.
 | 
      
         | 711 |  |  |  
 | 
      
         | 712 |  |  |    If LOCATION is the source location of token that is part of the
 | 
      
         | 713 |  |  |    replacement-list of a macro expansion return the file path of the
 | 
      
         | 714 |  |  |    macro expansion point.
 | 
      
         | 715 |  |  |  
 | 
      
         | 716 |  |  |    SET is the line map set LOCATION comes from.  */
 | 
      
         | 717 |  |  |  
 | 
      
         | 718 |  |  | const char*
 | 
      
         | 719 |  |  | linemap_get_expansion_filename (struct line_maps *set,
 | 
      
         | 720 |  |  |                                 source_location location)
 | 
      
         | 721 |  |  | {
 | 
      
         | 722 |  |  |   const struct line_map *map = NULL;
 | 
      
         | 723 |  |  |  
 | 
      
         | 724 |  |  |   if (location < RESERVED_LOCATION_COUNT)
 | 
      
         | 725 |  |  |     return NULL;
 | 
      
         | 726 |  |  |  
 | 
      
         | 727 |  |  |   location =
 | 
      
         | 728 |  |  |     linemap_macro_loc_to_exp_point (set, location, &map);
 | 
      
         | 729 |  |  |  
 | 
      
         | 730 |  |  |   return LINEMAP_FILE (map);
 | 
      
         | 731 |  |  | }
 | 
      
         | 732 |  |  |  
 | 
      
         | 733 |  |  | /* Return the name of the macro associated to MACRO_MAP.  */
 | 
      
         | 734 |  |  |  
 | 
      
         | 735 |  |  | const char*
 | 
      
         | 736 |  |  | linemap_map_get_macro_name (const struct line_map* macro_map)
 | 
      
         | 737 |  |  | {
 | 
      
         | 738 |  |  |   linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
 | 
      
         | 739 |  |  |   return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
 | 
      
         | 740 |  |  | }
 | 
      
         | 741 |  |  |  
 | 
      
         | 742 |  |  | /* Return a positive value if LOCATION is the locus of a token that is
 | 
      
         | 743 |  |  |    located in a system header, O otherwise. It returns 1 if LOCATION
 | 
      
         | 744 |  |  |    is the locus of a token that is located in a system header, and 2
 | 
      
         | 745 |  |  |    if LOCATION is the locus of a token located in a C system header
 | 
      
         | 746 |  |  |    that therefore needs to be extern "C" protected in C++.
 | 
      
         | 747 |  |  |  
 | 
      
         | 748 |  |  |    Note that this function returns 1 if LOCATION belongs to a token
 | 
      
         | 749 |  |  |    that is part of a macro replacement-list defined in a system
 | 
      
         | 750 |  |  |    header, but expanded in a non-system file.  */
 | 
      
         | 751 |  |  |  
 | 
      
         | 752 |  |  | int
 | 
      
         | 753 |  |  | linemap_location_in_system_header_p (struct line_maps *set,
 | 
      
         | 754 |  |  |                                      source_location location)
 | 
      
         | 755 |  |  | {
 | 
      
         | 756 |  |  |   const struct line_map *map = NULL;
 | 
      
         | 757 |  |  |  
 | 
      
         | 758 |  |  |   location =
 | 
      
         | 759 |  |  |     linemap_resolve_location (set, location, LRK_SPELLING_LOCATION, &map);
 | 
      
         | 760 |  |  |  
 | 
      
         | 761 |  |  |   if (location < RESERVED_LOCATION_COUNT)
 | 
      
         | 762 |  |  |     return false;
 | 
      
         | 763 |  |  |  
 | 
      
         | 764 |  |  |   return LINEMAP_SYSP (map);
 | 
      
         | 765 |  |  | }
 | 
      
         | 766 |  |  |  
 | 
      
         | 767 |  |  | /* Return TRUE if LOCATION is a source code location of a token coming
 | 
      
         | 768 |  |  |    from a macro replacement-list at a macro expansion point, FALSE
 | 
      
         | 769 |  |  |    otherwise.  */
 | 
      
         | 770 |  |  |  
 | 
      
         | 771 |  |  | bool
 | 
      
         | 772 |  |  | linemap_location_from_macro_expansion_p (struct line_maps *set,
 | 
      
         | 773 |  |  |                                          source_location location)
 | 
      
         | 774 |  |  | {
 | 
      
         | 775 |  |  |   linemap_assert (location <= MAX_SOURCE_LOCATION
 | 
      
         | 776 |  |  |                   && (set->highest_location
 | 
      
         | 777 |  |  |                       < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
 | 
      
         | 778 |  |  |   if (set == NULL)
 | 
      
         | 779 |  |  |     return false;
 | 
      
         | 780 |  |  |   return (location > set->highest_location);
 | 
      
         | 781 |  |  | }
 | 
      
         | 782 |  |  |  
 | 
      
         | 783 |  |  | /* Given two virtual locations *LOC0 and *LOC1, return the first
 | 
      
         | 784 |  |  |    common macro map in their macro expansion histories.  Return NULL
 | 
      
         | 785 |  |  |    if no common macro was found.  *LOC0 (resp. *LOC1) is set to the
 | 
      
         | 786 |  |  |    virtual location of the token inside the resulting macro.  */
 | 
      
         | 787 |  |  |  
 | 
      
         | 788 |  |  | static const struct line_map*
 | 
      
         | 789 |  |  | first_map_in_common_1 (struct line_maps *set,
 | 
      
         | 790 |  |  |                        source_location *loc0,
 | 
      
         | 791 |  |  |                        source_location *loc1)
 | 
      
         | 792 |  |  | {
 | 
      
         | 793 |  |  |   source_location l0 = *loc0, l1 = *loc1;
 | 
      
         | 794 |  |  |   const struct line_map *map0 = linemap_lookup (set, l0),
 | 
      
         | 795 |  |  |     *map1 = linemap_lookup (set, l1);
 | 
      
         | 796 |  |  |  
 | 
      
         | 797 |  |  |   while (linemap_macro_expansion_map_p (map0)
 | 
      
         | 798 |  |  |          && linemap_macro_expansion_map_p (map1)
 | 
      
         | 799 |  |  |          && (map0 != map1))
 | 
      
         | 800 |  |  |     {
 | 
      
         | 801 |  |  |       if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
 | 
      
         | 802 |  |  |         {
 | 
      
         | 803 |  |  |           l0 = linemap_macro_map_loc_to_exp_point (map0, l0);
 | 
      
         | 804 |  |  |           map0 = linemap_lookup (set, l0);
 | 
      
         | 805 |  |  |         }
 | 
      
         | 806 |  |  |       else
 | 
      
         | 807 |  |  |         {
 | 
      
         | 808 |  |  |           l1 = linemap_macro_map_loc_to_exp_point (map1, l1);
 | 
      
         | 809 |  |  |           map1 = linemap_lookup (set, l1);
 | 
      
         | 810 |  |  |         }
 | 
      
         | 811 |  |  |     }
 | 
      
         | 812 |  |  |  
 | 
      
         | 813 |  |  |   if (map0 == map1)
 | 
      
         | 814 |  |  |     {
 | 
      
         | 815 |  |  |       *loc0 = l0;
 | 
      
         | 816 |  |  |       *loc1 = l1;
 | 
      
         | 817 |  |  |       return map0;
 | 
      
         | 818 |  |  |     }
 | 
      
         | 819 |  |  |   return NULL;
 | 
      
         | 820 |  |  | }
 | 
      
         | 821 |  |  |  
 | 
      
         | 822 |  |  | /* Given two virtual locations LOC0 and LOC1, return the first common
 | 
      
         | 823 |  |  |    macro map in their macro expansion histories.  Return NULL if no
 | 
      
         | 824 |  |  |    common macro was found.  *RES_LOC0 (resp. *RES_LOC1) is set to the
 | 
      
         | 825 |  |  |    virtual location of the token inside the resulting macro, upon
 | 
      
         | 826 |  |  |    return of a non-NULL result.  */
 | 
      
         | 827 |  |  |  
 | 
      
         | 828 |  |  | static const struct line_map*
 | 
      
         | 829 |  |  | first_map_in_common (struct line_maps *set,
 | 
      
         | 830 |  |  |                      source_location loc0,
 | 
      
         | 831 |  |  |                      source_location loc1,
 | 
      
         | 832 |  |  |                      source_location  *res_loc0,
 | 
      
         | 833 |  |  |                      source_location  *res_loc1)
 | 
      
         | 834 |  |  | {
 | 
      
         | 835 |  |  |   *res_loc0 = loc0;
 | 
      
         | 836 |  |  |   *res_loc1 = loc1;
 | 
      
         | 837 |  |  |  
 | 
      
         | 838 |  |  |   return first_map_in_common_1 (set, res_loc0, res_loc1);
 | 
      
         | 839 |  |  | }
 | 
      
         | 840 |  |  |  
 | 
      
         | 841 |  |  | /* Return a positive value if PRE denotes the location of a token that
 | 
      
         | 842 |  |  |    comes before the token of POST, 0 if PRE denotes the location of
 | 
      
         | 843 |  |  |    the same token as the token for POST, and a negative value
 | 
      
         | 844 |  |  |    otherwise.  */
 | 
      
         | 845 |  |  |  
 | 
      
         | 846 |  |  | int
 | 
      
         | 847 |  |  | linemap_compare_locations (struct line_maps *set,
 | 
      
         | 848 |  |  |                            source_location  pre,
 | 
      
         | 849 |  |  |                            source_location post)
 | 
      
         | 850 |  |  | {
 | 
      
         | 851 |  |  |   bool pre_virtual_p, post_virtual_p;
 | 
      
         | 852 |  |  |   source_location l0 = pre, l1 = post;
 | 
      
         | 853 |  |  |  
 | 
      
         | 854 |  |  |   if (l0 == l1)
 | 
      
         | 855 |  |  |     return 0;
 | 
      
         | 856 |  |  |  
 | 
      
         | 857 |  |  |   if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
 | 
      
         | 858 |  |  |     l0 = linemap_resolve_location (set, l0,
 | 
      
         | 859 |  |  |                                    LRK_MACRO_EXPANSION_POINT,
 | 
      
         | 860 |  |  |                                    NULL);
 | 
      
         | 861 |  |  |  
 | 
      
         | 862 |  |  |   if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
 | 
      
         | 863 |  |  |     l1 = linemap_resolve_location (set, l1,
 | 
      
         | 864 |  |  |                                    LRK_MACRO_EXPANSION_POINT,
 | 
      
         | 865 |  |  |                                    NULL);
 | 
      
         | 866 |  |  |  
 | 
      
         | 867 |  |  |   if (l0 == l1
 | 
      
         | 868 |  |  |       && pre_virtual_p
 | 
      
         | 869 |  |  |       && post_virtual_p)
 | 
      
         | 870 |  |  |     {
 | 
      
         | 871 |  |  |       /* So pre and post represent two tokens that are present in a
 | 
      
         | 872 |  |  |          same macro expansion.  Let's see if the token for pre was
 | 
      
         | 873 |  |  |          before the token for post in that expansion.  */
 | 
      
         | 874 |  |  |       unsigned i0, i1;
 | 
      
         | 875 |  |  |       const struct line_map *map =
 | 
      
         | 876 |  |  |         first_map_in_common (set, pre, post, &l0, &l1);
 | 
      
         | 877 |  |  |  
 | 
      
         | 878 |  |  |       if (map == NULL)
 | 
      
         | 879 |  |  |         /* This should not be possible.  */
 | 
      
         | 880 |  |  |         abort ();
 | 
      
         | 881 |  |  |  
 | 
      
         | 882 |  |  |       i0 = l0 - MAP_START_LOCATION (map);
 | 
      
         | 883 |  |  |       i1 = l1 - MAP_START_LOCATION (map);
 | 
      
         | 884 |  |  |       return i1 - i0;
 | 
      
         | 885 |  |  |     }
 | 
      
         | 886 |  |  |  
 | 
      
         | 887 |  |  |   return l1 - l0;
 | 
      
         | 888 |  |  | }
 | 
      
         | 889 |  |  |  
 | 
      
         | 890 |  |  | /* Print an include trace, for e.g. the -H option of the preprocessor.  */
 | 
      
         | 891 |  |  |  
 | 
      
         | 892 |  |  | static void
 | 
      
         | 893 |  |  | trace_include (const struct line_maps *set, const struct line_map *map)
 | 
      
         | 894 |  |  | {
 | 
      
         | 895 |  |  |   unsigned int i = set->depth;
 | 
      
         | 896 |  |  |  
 | 
      
         | 897 |  |  |   while (--i)
 | 
      
         | 898 |  |  |     putc ('.', stderr);
 | 
      
         | 899 |  |  |  
 | 
      
         | 900 |  |  |   fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
 | 
      
         | 901 |  |  | }
 | 
      
         | 902 |  |  |  
 | 
      
         | 903 |  |  | /* Return the spelling location of the token wherever it comes from,
 | 
      
         | 904 |  |  |    whether part of a macro definition or not.
 | 
      
         | 905 |  |  |  
 | 
      
         | 906 |  |  |    This is a subroutine for linemap_resolve_location.  */
 | 
      
         | 907 |  |  |  
 | 
      
         | 908 |  |  | static source_location
 | 
      
         | 909 |  |  | linemap_macro_loc_to_spelling_point (struct line_maps *set,
 | 
      
         | 910 |  |  |                                      source_location location,
 | 
      
         | 911 |  |  |                                      const struct line_map **original_map)
 | 
      
         | 912 |  |  | {
 | 
      
         | 913 |  |  |   struct line_map *map;
 | 
      
         | 914 |  |  |  
 | 
      
         | 915 |  |  |   linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
 | 
      
         | 916 |  |  |  
 | 
      
         | 917 |  |  |   while (true)
 | 
      
         | 918 |  |  |     {
 | 
      
         | 919 |  |  |       map = (struct line_map*) linemap_lookup (set, location);
 | 
      
         | 920 |  |  |       if (!linemap_macro_expansion_map_p (map))
 | 
      
         | 921 |  |  |         break;
 | 
      
         | 922 |  |  |  
 | 
      
         | 923 |  |  |       location =
 | 
      
         | 924 |  |  |         linemap_macro_map_loc_unwind_toward_spelling (map, location);
 | 
      
         | 925 |  |  |     }
 | 
      
         | 926 |  |  |  
 | 
      
         | 927 |  |  |   if (original_map)
 | 
      
         | 928 |  |  |     *original_map = map;
 | 
      
         | 929 |  |  |   return location;
 | 
      
         | 930 |  |  | }
 | 
      
         | 931 |  |  |  
 | 
      
         | 932 |  |  | /* If LOCATION is the source location of a token that belongs to a
 | 
      
         | 933 |  |  |    macro replacement-list -- as part of a macro expansion -- then
 | 
      
         | 934 |  |  |    return the location of the token at the definition point of the
 | 
      
         | 935 |  |  |    macro.  Otherwise, return LOCATION.  SET is the set of maps
 | 
      
         | 936 |  |  |    location come from.  ORIGINAL_MAP is an output parm. If non NULL,
 | 
      
         | 937 |  |  |    the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
 | 
      
         | 938 |  |  |    returned location comes from.
 | 
      
         | 939 |  |  |  
 | 
      
         | 940 |  |  |    This is a subroutine of linemap_resolve_location.  */
 | 
      
         | 941 |  |  |  
 | 
      
         | 942 |  |  | static source_location
 | 
      
         | 943 |  |  | linemap_macro_loc_to_def_point (struct line_maps *set,
 | 
      
         | 944 |  |  |                                 source_location location,
 | 
      
         | 945 |  |  |                                 const struct line_map **original_map)
 | 
      
         | 946 |  |  | {
 | 
      
         | 947 |  |  |   struct line_map *map;
 | 
      
         | 948 |  |  |  
 | 
      
         | 949 |  |  |   linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
 | 
      
         | 950 |  |  |  
 | 
      
         | 951 |  |  |   while (true)
 | 
      
         | 952 |  |  |     {
 | 
      
         | 953 |  |  |       map = (struct line_map*) linemap_lookup (set, location);
 | 
      
         | 954 |  |  |       if (!linemap_macro_expansion_map_p (map))
 | 
      
         | 955 |  |  |         break;
 | 
      
         | 956 |  |  |  
 | 
      
         | 957 |  |  |       location =
 | 
      
         | 958 |  |  |         linemap_macro_map_loc_to_def_point (map, location);
 | 
      
         | 959 |  |  |     }
 | 
      
         | 960 |  |  |  
 | 
      
         | 961 |  |  |   if (original_map)
 | 
      
         | 962 |  |  |     *original_map = map;
 | 
      
         | 963 |  |  |   return location;
 | 
      
         | 964 |  |  | }
 | 
      
         | 965 |  |  |  
 | 
      
         | 966 |  |  | /* If LOCATION is the source location of a token that belongs to a
 | 
      
         | 967 |  |  |    macro replacement-list -- at a macro expansion point -- then return
 | 
      
         | 968 |  |  |    the location of the topmost expansion point of the macro.  We say
 | 
      
         | 969 |  |  |    topmost because if we are in the context of a nested macro
 | 
      
         | 970 |  |  |    expansion, the function returns the source location of the first
 | 
      
         | 971 |  |  |    macro expansion that triggered the nested expansions.
 | 
      
         | 972 |  |  |  
 | 
      
         | 973 |  |  |    Otherwise, return LOCATION.  SET is the set of maps location come
 | 
      
         | 974 |  |  |    from.  ORIGINAL_MAP is an output parm. If non NULL, the function
 | 
      
         | 975 |  |  |    sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
 | 
      
         | 976 |  |  |    location comes from.
 | 
      
         | 977 |  |  |  
 | 
      
         | 978 |  |  |    This is a subroutine of linemap_resolve_location.  */
 | 
      
         | 979 |  |  |  
 | 
      
         | 980 |  |  | static source_location
 | 
      
         | 981 |  |  | linemap_macro_loc_to_exp_point (struct line_maps *set,
 | 
      
         | 982 |  |  |                                 source_location location,
 | 
      
         | 983 |  |  |                                 const struct line_map **original_map)
 | 
      
         | 984 |  |  | {
 | 
      
         | 985 |  |  |   struct line_map *map;
 | 
      
         | 986 |  |  |  
 | 
      
         | 987 |  |  |   linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
 | 
      
         | 988 |  |  |  
 | 
      
         | 989 |  |  |   while (true)
 | 
      
         | 990 |  |  |     {
 | 
      
         | 991 |  |  |       map = (struct line_map*) linemap_lookup (set, location);
 | 
      
         | 992 |  |  |       if (!linemap_macro_expansion_map_p (map))
 | 
      
         | 993 |  |  |         break;
 | 
      
         | 994 |  |  |       location = linemap_macro_map_loc_to_exp_point (map, location);
 | 
      
         | 995 |  |  |     }
 | 
      
         | 996 |  |  |  
 | 
      
         | 997 |  |  |   if (original_map)
 | 
      
         | 998 |  |  |     *original_map = map;
 | 
      
         | 999 |  |  |   return location;
 | 
      
         | 1000 |  |  | }
 | 
      
         | 1001 |  |  |  
 | 
      
         | 1002 |  |  | /* Resolve a virtual location into either a spelling location, an
 | 
      
         | 1003 |  |  |    expansion point location or a token argument replacement point
 | 
      
         | 1004 |  |  |    location.  Return the map that encodes the virtual location as well
 | 
      
         | 1005 |  |  |    as the resolved location.
 | 
      
         | 1006 |  |  |  
 | 
      
         | 1007 |  |  |    If LOC is *NOT* the location of a token resulting from the
 | 
      
         | 1008 |  |  |    expansion of a macro, then the parameter LRK (which stands for
 | 
      
         | 1009 |  |  |    Location Resolution Kind) is ignored and the resulting location
 | 
      
         | 1010 |  |  |    just equals the one given in argument.
 | 
      
         | 1011 |  |  |  
 | 
      
         | 1012 |  |  |    Now if LOC *IS* the location of a token resulting from the
 | 
      
         | 1013 |  |  |    expansion of a macro, this is what happens.
 | 
      
         | 1014 |  |  |  
 | 
      
         | 1015 |  |  |    * If LRK is set to LRK_MACRO_EXPANSION_POINT
 | 
      
         | 1016 |  |  |    -------------------------------
 | 
      
         | 1017 |  |  |  
 | 
      
         | 1018 |  |  |    The virtual location is resolved to the location to the locus of
 | 
      
         | 1019 |  |  |    the expansion point of the macro.
 | 
      
         | 1020 |  |  |  
 | 
      
         | 1021 |  |  |    * If LRK is set to LRK_SPELLING_LOCATION
 | 
      
         | 1022 |  |  |    -------------------------------------
 | 
      
         | 1023 |  |  |  
 | 
      
         | 1024 |  |  |    The virtual location is resolved to the location to the locus where
 | 
      
         | 1025 |  |  |    the token has been spelled in the source. This can follow through
 | 
      
         | 1026 |  |  |    all the macro expansions that led to the token.
 | 
      
         | 1027 |  |  |  
 | 
      
         | 1028 |  |  |    * If LRK is set to LRK_MACRO_PARM_REPLACEMENT_POINT
 | 
      
         | 1029 |  |  |    --------------------------------------
 | 
      
         | 1030 |  |  |  
 | 
      
         | 1031 |  |  |    If LOC is the locus of a token that is an argument of a
 | 
      
         | 1032 |  |  |    function-like macro [replacing a parameter in the replacement list
 | 
      
         | 1033 |  |  |    of the macro] the virtual location is resolved to the locus of the
 | 
      
         | 1034 |  |  |    parameter that is replaced, in the context of the definition of the
 | 
      
         | 1035 |  |  |    macro.
 | 
      
         | 1036 |  |  |  
 | 
      
         | 1037 |  |  |    If LOC is the locus of a token that is not an argument of a
 | 
      
         | 1038 |  |  |    function-like macro, then the function behaves as if LRK was set to
 | 
      
         | 1039 |  |  |    LRK_SPELLING_LOCATION.
 | 
      
         | 1040 |  |  |  
 | 
      
         | 1041 |  |  |    If MAP is non-NULL, *MAP is set to the map of the resolved
 | 
      
         | 1042 |  |  |    location.  Note that if the resturned location wasn't originally
 | 
      
         | 1043 |  |  |    encoded by a map, the *MAP is set to NULL.  This can happen if LOC
 | 
      
         | 1044 |  |  |    resolves to a location reserved for the client code, like
 | 
      
         | 1045 |  |  |    UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC.  */
 | 
      
         | 1046 |  |  |  
 | 
      
         | 1047 |  |  | source_location
 | 
      
         | 1048 |  |  | linemap_resolve_location (struct line_maps *set,
 | 
      
         | 1049 |  |  |                           source_location loc,
 | 
      
         | 1050 |  |  |                           enum location_resolution_kind lrk,
 | 
      
         | 1051 |  |  |                           const struct line_map **map)
 | 
      
         | 1052 |  |  | {
 | 
      
         | 1053 |  |  |   if (loc < RESERVED_LOCATION_COUNT)
 | 
      
         | 1054 |  |  |     {
 | 
      
         | 1055 |  |  |       /* A reserved location wasn't encoded in a map.  Let's return a
 | 
      
         | 1056 |  |  |          NULL map here, just like what linemap_ordinary_map_lookup
 | 
      
         | 1057 |  |  |          does.  */
 | 
      
         | 1058 |  |  |       if (map)
 | 
      
         | 1059 |  |  |         *map = NULL;
 | 
      
         | 1060 |  |  |       return loc;
 | 
      
         | 1061 |  |  |     }
 | 
      
         | 1062 |  |  |  
 | 
      
         | 1063 |  |  |   switch (lrk)
 | 
      
         | 1064 |  |  |     {
 | 
      
         | 1065 |  |  |     case LRK_MACRO_EXPANSION_POINT:
 | 
      
         | 1066 |  |  |       loc = linemap_macro_loc_to_exp_point (set, loc, map);
 | 
      
         | 1067 |  |  |       break;
 | 
      
         | 1068 |  |  |     case LRK_SPELLING_LOCATION:
 | 
      
         | 1069 |  |  |       loc = linemap_macro_loc_to_spelling_point (set, loc, map);
 | 
      
         | 1070 |  |  |       break;
 | 
      
         | 1071 |  |  |     case LRK_MACRO_DEFINITION_LOCATION:
 | 
      
         | 1072 |  |  |       loc = linemap_macro_loc_to_def_point (set, loc, map);
 | 
      
         | 1073 |  |  |       break;
 | 
      
         | 1074 |  |  |     default:
 | 
      
         | 1075 |  |  |       abort ();
 | 
      
         | 1076 |  |  |     }
 | 
      
         | 1077 |  |  |   return loc;
 | 
      
         | 1078 |  |  | }
 | 
      
         | 1079 |  |  |  
 | 
      
         | 1080 |  |  | /*
 | 
      
         | 1081 |  |  |    Suppose that LOC is the virtual location of a token T coming from
 | 
      
         | 1082 |  |  |    the expansion of a macro M.  This function then steps up to get the
 | 
      
         | 1083 |  |  |    location L of the point where M got expanded.  If L is a spelling
 | 
      
         | 1084 |  |  |    location inside a macro expansion M', then this function returns
 | 
      
         | 1085 |  |  |    the locus of the point where M' was expanded.  Said otherwise, this
 | 
      
         | 1086 |  |  |    function returns the location of T in the context that triggered
 | 
      
         | 1087 |  |  |    the expansion of M.
 | 
      
         | 1088 |  |  |  
 | 
      
         | 1089 |  |  |    *LOC_MAP must be set to the map of LOC.  This function then sets it
 | 
      
         | 1090 |  |  |    to the map of the returned location.  */
 | 
      
         | 1091 |  |  |  
 | 
      
         | 1092 |  |  | source_location
 | 
      
         | 1093 |  |  | linemap_unwind_toward_expansion (struct line_maps *set,
 | 
      
         | 1094 |  |  |                                  source_location loc,
 | 
      
         | 1095 |  |  |                                  const struct line_map **map)
 | 
      
         | 1096 |  |  | {
 | 
      
         | 1097 |  |  |   source_location resolved_location;
 | 
      
         | 1098 |  |  |   const struct line_map *resolved_map;
 | 
      
         | 1099 |  |  |  
 | 
      
         | 1100 |  |  |   resolved_location =
 | 
      
         | 1101 |  |  |     linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
 | 
      
         | 1102 |  |  |   resolved_map = linemap_lookup (set, resolved_location);
 | 
      
         | 1103 |  |  |  
 | 
      
         | 1104 |  |  |   if (!linemap_macro_expansion_map_p (resolved_map))
 | 
      
         | 1105 |  |  |     {
 | 
      
         | 1106 |  |  |       resolved_location = linemap_macro_map_loc_to_exp_point (*map, loc);
 | 
      
         | 1107 |  |  |       resolved_map = linemap_lookup (set, resolved_location);
 | 
      
         | 1108 |  |  |     }
 | 
      
         | 1109 |  |  |  
 | 
      
         | 1110 |  |  |   *map = resolved_map;
 | 
      
         | 1111 |  |  |   return resolved_location;
 | 
      
         | 1112 |  |  | }
 | 
      
         | 1113 |  |  |  
 | 
      
         | 1114 |  |  | /* Expand source code location LOC and return a user readable source
 | 
      
         | 1115 |  |  |    code location.  LOC must be a spelling (non-virtual) location.  If
 | 
      
         | 1116 |  |  |    it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
 | 
      
         | 1117 |  |  |    location is returned.  */
 | 
      
         | 1118 |  |  |  
 | 
      
         | 1119 |  |  | expanded_location
 | 
      
         | 1120 |  |  | linemap_expand_location (struct line_maps *set,
 | 
      
         | 1121 |  |  |                          const struct line_map *map,
 | 
      
         | 1122 |  |  |                          source_location loc)
 | 
      
         | 1123 |  |  |  
 | 
      
         | 1124 |  |  | {
 | 
      
         | 1125 |  |  |   expanded_location xloc;
 | 
      
         | 1126 |  |  |  
 | 
      
         | 1127 |  |  |   memset (&xloc, 0, sizeof (xloc));
 | 
      
         | 1128 |  |  |  
 | 
      
         | 1129 |  |  |   if (loc < RESERVED_LOCATION_COUNT)
 | 
      
         | 1130 |  |  |     /* The location for this token wasn't generated from a line map.
 | 
      
         | 1131 |  |  |        It was probably a location for a builtin token, chosen by some
 | 
      
         | 1132 |  |  |        client code.  Let's not try to expand the location in that
 | 
      
         | 1133 |  |  |        case.  */;
 | 
      
         | 1134 |  |  |   else if (map == NULL)
 | 
      
         | 1135 |  |  |     /* We shouldn't be getting a NULL map with a location that is not
 | 
      
         | 1136 |  |  |        reserved by the client code.  */
 | 
      
         | 1137 |  |  |     abort ();
 | 
      
         | 1138 |  |  |   else
 | 
      
         | 1139 |  |  |     {
 | 
      
         | 1140 |  |  |       /* MAP must be an ordinary map and LOC must be non-virtual,
 | 
      
         | 1141 |  |  |          encoded into this map, obviously; the accessors used on MAP
 | 
      
         | 1142 |  |  |          below ensure it is ordinary.  Let's just assert the
 | 
      
         | 1143 |  |  |          non-virtualness of LOC here.  */
 | 
      
         | 1144 |  |  |       if (linemap_location_from_macro_expansion_p (set, loc))
 | 
      
         | 1145 |  |  |         abort ();
 | 
      
         | 1146 |  |  |  
 | 
      
         | 1147 |  |  |       xloc.file = LINEMAP_FILE (map);
 | 
      
         | 1148 |  |  |       xloc.line = SOURCE_LINE (map, loc);
 | 
      
         | 1149 |  |  |       xloc.column = SOURCE_COLUMN (map, loc);
 | 
      
         | 1150 |  |  |       xloc.sysp = LINEMAP_SYSP (map) != 0;
 | 
      
         | 1151 |  |  |     }
 | 
      
         | 1152 |  |  |  
 | 
      
         | 1153 |  |  |   return xloc;
 | 
      
         | 1154 |  |  | }
 | 
      
         | 1155 |  |  |  
 | 
      
         | 1156 |  |  |  
 | 
      
         | 1157 |  |  | /* Dump line map at index IX in line table SET to STREAM.  If STREAM
 | 
      
         | 1158 |  |  |    is NULL, use stderr.  IS_MACRO is true if the caller wants to
 | 
      
         | 1159 |  |  |    dump a macro map, false otherwise.  */
 | 
      
         | 1160 |  |  |  
 | 
      
         | 1161 |  |  | void
 | 
      
         | 1162 |  |  | linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
 | 
      
         | 1163 |  |  | {
 | 
      
         | 1164 |  |  |   const char *lc_reasons_v[LC_ENTER_MACRO + 1]
 | 
      
         | 1165 |  |  |       = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
 | 
      
         | 1166 |  |  |           "LC_ENTER_MACRO" };
 | 
      
         | 1167 |  |  |   const char *reason;
 | 
      
         | 1168 |  |  |   struct line_map *map;
 | 
      
         | 1169 |  |  |  
 | 
      
         | 1170 |  |  |   if (stream == NULL)
 | 
      
         | 1171 |  |  |     stream = stderr;
 | 
      
         | 1172 |  |  |  
 | 
      
         | 1173 |  |  |   if (!is_macro)
 | 
      
         | 1174 |  |  |     map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
 | 
      
         | 1175 |  |  |   else
 | 
      
         | 1176 |  |  |     map = LINEMAPS_MACRO_MAP_AT (set, ix);
 | 
      
         | 1177 |  |  |  
 | 
      
         | 1178 |  |  |   reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???";
 | 
      
         | 1179 |  |  |  
 | 
      
         | 1180 |  |  |   fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
 | 
      
         | 1181 |  |  |            ix, (void *) map, map->start_location, reason,
 | 
      
         | 1182 |  |  |            (!is_macro && ORDINARY_MAP_IN_SYSTEM_HEADER_P (map)) ? "yes" : "no");
 | 
      
         | 1183 |  |  |   if (!is_macro)
 | 
      
         | 1184 |  |  |     {
 | 
      
         | 1185 |  |  |       unsigned includer_ix;
 | 
      
         | 1186 |  |  |       struct line_map *includer_map;
 | 
      
         | 1187 |  |  |  
 | 
      
         | 1188 |  |  |       includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (map);
 | 
      
         | 1189 |  |  |       includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
 | 
      
         | 1190 |  |  |                      ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
 | 
      
         | 1191 |  |  |                      : NULL;
 | 
      
         | 1192 |  |  |  
 | 
      
         | 1193 |  |  |       fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (map),
 | 
      
         | 1194 |  |  |                ORDINARY_MAP_STARTING_LINE_NUMBER (map));
 | 
      
         | 1195 |  |  |       fprintf (stream, "Included from: [%d] %s\n", includer_ix,
 | 
      
         | 1196 |  |  |                includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
 | 
      
         | 1197 |  |  |     }
 | 
      
         | 1198 |  |  |   else
 | 
      
         | 1199 |  |  |     fprintf (stream, "Macro: %s (%u tokens)\n",
 | 
      
         | 1200 |  |  |              linemap_map_get_macro_name (map),
 | 
      
         | 1201 |  |  |              MACRO_MAP_NUM_MACRO_TOKENS (map));
 | 
      
         | 1202 |  |  |  
 | 
      
         | 1203 |  |  |   fprintf (stream, "\n");
 | 
      
         | 1204 |  |  | }
 | 
      
         | 1205 |  |  |  
 | 
      
         | 1206 |  |  |  
 | 
      
         | 1207 |  |  | /* Dump debugging information about source location LOC into the file
 | 
      
         | 1208 |  |  |    stream STREAM. SET is the line map set LOC comes from.  */
 | 
      
         | 1209 |  |  |  
 | 
      
         | 1210 |  |  | void
 | 
      
         | 1211 |  |  | linemap_dump_location (struct line_maps *set,
 | 
      
         | 1212 |  |  |                        source_location loc,
 | 
      
         | 1213 |  |  |                        FILE *stream)
 | 
      
         | 1214 |  |  | {
 | 
      
         | 1215 |  |  |   const struct line_map *map;
 | 
      
         | 1216 |  |  |   source_location location;
 | 
      
         | 1217 |  |  |   const char *path = "", *from = "";
 | 
      
         | 1218 |  |  |   int l = -1, c = -1, s = -1, e = -1;
 | 
      
         | 1219 |  |  |  
 | 
      
         | 1220 |  |  |   if (loc == 0)
 | 
      
         | 1221 |  |  |     return;
 | 
      
         | 1222 |  |  |  
 | 
      
         | 1223 |  |  |   location =
 | 
      
         | 1224 |  |  |     linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
 | 
      
         | 1225 |  |  |  
 | 
      
         | 1226 |  |  |   if (map == NULL)
 | 
      
         | 1227 |  |  |     /* Only reserved locations can be tolerated in this case.  */
 | 
      
         | 1228 |  |  |     linemap_assert (location < RESERVED_LOCATION_COUNT);
 | 
      
         | 1229 |  |  |   else
 | 
      
         | 1230 |  |  |     {
 | 
      
         | 1231 |  |  |       path = LINEMAP_FILE (map);
 | 
      
         | 1232 |  |  |       l = SOURCE_LINE (map, location);
 | 
      
         | 1233 |  |  |       c = SOURCE_COLUMN (map, location);
 | 
      
         | 1234 |  |  |       s = LINEMAP_SYSP (map) != 0;
 | 
      
         | 1235 |  |  |       e = location != loc;
 | 
      
         | 1236 |  |  |       if (e)
 | 
      
         | 1237 |  |  |         from = "N/A";
 | 
      
         | 1238 |  |  |       else
 | 
      
         | 1239 |  |  |         from = (INCLUDED_FROM (set, map))
 | 
      
         | 1240 |  |  |           ? LINEMAP_FILE (INCLUDED_FROM (set, map))
 | 
      
         | 1241 |  |  |           : "<NULL>";
 | 
      
         | 1242 |  |  |     }
 | 
      
         | 1243 |  |  |  
 | 
      
         | 1244 |  |  |   /* P: path, L: line, C: column, S: in-system-header, M: map address,
 | 
      
         | 1245 |  |  |      E: macro expansion?, LOC: original location, R: resolved location   */
 | 
      
         | 1246 |  |  |   fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
 | 
      
         | 1247 |  |  |            path, from, l, c, s, (void*)map, e, loc, location);
 | 
      
         | 1248 |  |  | }
 | 
      
         | 1249 |  |  |  
 | 
      
         | 1250 |  |  | /* Compute and return statistics about the memory consumption of some
 | 
      
         | 1251 |  |  |    parts of the line table SET.  */
 | 
      
         | 1252 |  |  |  
 | 
      
         | 1253 |  |  | void
 | 
      
         | 1254 |  |  | linemap_get_statistics (struct line_maps *set,
 | 
      
         | 1255 |  |  |                         struct linemap_stats *s)
 | 
      
         | 1256 |  |  | {
 | 
      
         | 1257 |  |  |   long ordinary_maps_allocated_size, ordinary_maps_used_size,
 | 
      
         | 1258 |  |  |     macro_maps_allocated_size, macro_maps_used_size,
 | 
      
         | 1259 |  |  |     macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
 | 
      
         | 1260 |  |  |  
 | 
      
         | 1261 |  |  |   struct line_map *cur_map;
 | 
      
         | 1262 |  |  |  
 | 
      
         | 1263 |  |  |   ordinary_maps_allocated_size =
 | 
      
         | 1264 |  |  |     LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map);
 | 
      
         | 1265 |  |  |  
 | 
      
         | 1266 |  |  |   ordinary_maps_used_size =
 | 
      
         | 1267 |  |  |     LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map);
 | 
      
         | 1268 |  |  |  
 | 
      
         | 1269 |  |  |   macro_maps_allocated_size =
 | 
      
         | 1270 |  |  |     LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map);
 | 
      
         | 1271 |  |  |  
 | 
      
         | 1272 |  |  |   for (cur_map = LINEMAPS_MACRO_MAPS (set);
 | 
      
         | 1273 |  |  |        cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
 | 
      
         | 1274 |  |  |        ++cur_map)
 | 
      
         | 1275 |  |  |     {
 | 
      
         | 1276 |  |  |       unsigned i;
 | 
      
         | 1277 |  |  |  
 | 
      
         | 1278 |  |  |       linemap_assert (linemap_macro_expansion_map_p (cur_map));
 | 
      
         | 1279 |  |  |  
 | 
      
         | 1280 |  |  |       macro_maps_locations_size +=
 | 
      
         | 1281 |  |  |         2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
 | 
      
         | 1282 |  |  |  
 | 
      
         | 1283 |  |  |       for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
 | 
      
         | 1284 |  |  |         {
 | 
      
         | 1285 |  |  |           if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
 | 
      
         | 1286 |  |  |               MACRO_MAP_LOCATIONS (cur_map)[i + 1])
 | 
      
         | 1287 |  |  |             duplicated_macro_maps_locations_size +=
 | 
      
         | 1288 |  |  |               sizeof (source_location);
 | 
      
         | 1289 |  |  |         }
 | 
      
         | 1290 |  |  |     }
 | 
      
         | 1291 |  |  |  
 | 
      
         | 1292 |  |  |   macro_maps_used_size =
 | 
      
         | 1293 |  |  |     LINEMAPS_MACRO_USED (set) * sizeof (struct line_map);
 | 
      
         | 1294 |  |  |  
 | 
      
         | 1295 |  |  |   s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
 | 
      
         | 1296 |  |  |   s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
 | 
      
         | 1297 |  |  |   s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
 | 
      
         | 1298 |  |  |   s->ordinary_maps_used_size = ordinary_maps_used_size;
 | 
      
         | 1299 |  |  |   s->num_expanded_macros = num_expanded_macros_counter;
 | 
      
         | 1300 |  |  |   s->num_macro_tokens = num_macro_tokens_counter;
 | 
      
         | 1301 |  |  |   s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
 | 
      
         | 1302 |  |  |   s->macro_maps_allocated_size = macro_maps_allocated_size;
 | 
      
         | 1303 |  |  |   s->macro_maps_locations_size = macro_maps_locations_size;
 | 
      
         | 1304 |  |  |   s->macro_maps_used_size = macro_maps_used_size;
 | 
      
         | 1305 |  |  |   s->duplicated_macro_maps_locations_size =
 | 
      
         | 1306 |  |  |     duplicated_macro_maps_locations_size;
 | 
      
         | 1307 |  |  | }
 | 
      
         | 1308 |  |  |  
 | 
      
         | 1309 |  |  |  
 | 
      
         | 1310 |  |  | /* Dump line table SET to STREAM.  If STREAM is NULL, stderr is used.
 | 
      
         | 1311 |  |  |    NUM_ORDINARY specifies how many ordinary maps to dump.  NUM_MACRO
 | 
      
         | 1312 |  |  |    specifies how many macro maps to dump.  */
 | 
      
         | 1313 |  |  |  
 | 
      
         | 1314 |  |  | void
 | 
      
         | 1315 |  |  | line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
 | 
      
         | 1316 |  |  |                  unsigned int num_macro)
 | 
      
         | 1317 |  |  | {
 | 
      
         | 1318 |  |  |   unsigned int i;
 | 
      
         | 1319 |  |  |  
 | 
      
         | 1320 |  |  |   if (set == NULL)
 | 
      
         | 1321 |  |  |     return;
 | 
      
         | 1322 |  |  |  
 | 
      
         | 1323 |  |  |   if (stream == NULL)
 | 
      
         | 1324 |  |  |     stream = stderr;
 | 
      
         | 1325 |  |  |  
 | 
      
         | 1326 |  |  |   fprintf (stream, "# of ordinary maps:  %d\n", LINEMAPS_ORDINARY_USED (set));
 | 
      
         | 1327 |  |  |   fprintf (stream, "# of macro maps:     %d\n", LINEMAPS_MACRO_USED (set));
 | 
      
         | 1328 |  |  |   fprintf (stream, "Include stack depth: %d\n", set->depth);
 | 
      
         | 1329 |  |  |   fprintf (stream, "Highest location:    %u\n", set->highest_location);
 | 
      
         | 1330 |  |  |  
 | 
      
         | 1331 |  |  |   if (num_ordinary)
 | 
      
         | 1332 |  |  |     {
 | 
      
         | 1333 |  |  |       fprintf (stream, "\nOrdinary line maps\n");
 | 
      
         | 1334 |  |  |       for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
 | 
      
         | 1335 |  |  |         linemap_dump (stream, set, i, false);
 | 
      
         | 1336 |  |  |       fprintf (stream, "\n");
 | 
      
         | 1337 |  |  |     }
 | 
      
         | 1338 |  |  |  
 | 
      
         | 1339 |  |  |   if (num_macro)
 | 
      
         | 1340 |  |  |     {
 | 
      
         | 1341 |  |  |       fprintf (stream, "\nMacro line maps\n");
 | 
      
         | 1342 |  |  |       for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
 | 
      
         | 1343 |  |  |         linemap_dump (stream, set, i, true);
 | 
      
         | 1344 |  |  |       fprintf (stream, "\n");
 | 
      
         | 1345 |  |  |     }
 | 
      
         | 1346 |  |  | }
 |