OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libcpp/] [line-map.c] - Blame information for rev 804

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.