mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-11 01:40:11 +08:00
libcpp/input.c: Add a way to visualize the linemaps (-fdump-internal-locations)
gcc/ChangeLog: * common.opt (fdump-internal-locations): New option. * input.c: Include diagnostic-core.h. (get_end_location): New function. (write_digit): New function. (write_digit_row): New function. (dump_location_range): New function. (dump_labelled_location_range): New function. (dump_location_info): New function. * input.h (dump_location_info): New prototype. * toplev.c (compile_file): Handle flag_dump_locations. libcpp/ChangeLog: * include/line-map.h (source_location): Add a reference to location-example.txt to the descriptive comment. * location-example.txt: New file. From-SVN: r223163
This commit is contained in:
parent
49d50b6b8f
commit
ba4ad400f1
@ -1,3 +1,16 @@
|
||||
2015-05-13 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* common.opt (fdump-internal-locations): New option.
|
||||
* input.c: Include diagnostic-core.h.
|
||||
(get_end_location): New function.
|
||||
(write_digit): New function.
|
||||
(write_digit_row): New function.
|
||||
(dump_location_range): New function.
|
||||
(dump_labelled_location_range): New function.
|
||||
(dump_location_info): New function.
|
||||
* input.h (dump_location_info): New prototype.
|
||||
* toplev.c (compile_file): Handle flag_dump_locations.
|
||||
|
||||
2015-05-13 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gimple-expr.h (is_gimple_constant): Reorder.
|
||||
|
@ -1166,6 +1166,10 @@ Common Driver Var(flag_report_bug)
|
||||
Collect and dump debug information into temporary file if ICE in C/C++
|
||||
compiler occured.
|
||||
|
||||
fdump-internal-locations
|
||||
Common Var(flag_dump_locations) Init(0)
|
||||
Dump detailed information on GCC's internal representation of source code locations
|
||||
|
||||
fdump-passes
|
||||
Common Var(flag_dump_passes) Init(0)
|
||||
Dump optimization passes
|
||||
|
224
gcc/input.c
224
gcc/input.c
@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "intl.h"
|
||||
#include "input.h"
|
||||
#include "vec.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
/* This is a cache used by get_next_line to store the content of a
|
||||
file to be searched for file lines. */
|
||||
@ -869,3 +870,226 @@ dump_line_table_statistics (void)
|
||||
STAT_LABEL (total_used_map_size));
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
/* Get location one beyond the final location in ordinary map IDX. */
|
||||
|
||||
static source_location
|
||||
get_end_location (struct line_maps *set, unsigned int idx)
|
||||
{
|
||||
if (idx == LINEMAPS_ORDINARY_USED (set) - 1)
|
||||
return set->highest_location;
|
||||
|
||||
struct line_map *next_map = LINEMAPS_ORDINARY_MAP_AT (set, idx + 1);
|
||||
return MAP_START_LOCATION (next_map);
|
||||
}
|
||||
|
||||
/* Helper function for write_digit_row. */
|
||||
|
||||
static void
|
||||
write_digit (FILE *stream, int digit)
|
||||
{
|
||||
fputc ('0' + (digit % 10), stream);
|
||||
}
|
||||
|
||||
/* Helper function for dump_location_info.
|
||||
Write a row of numbers to STREAM, numbering a source line,
|
||||
giving the units, tens, hundreds etc of the column number. */
|
||||
|
||||
static void
|
||||
write_digit_row (FILE *stream, int indent,
|
||||
source_location loc, int max_col, int divisor)
|
||||
{
|
||||
fprintf (stream, "%*c", indent, ' ');
|
||||
fprintf (stream, "|");
|
||||
for (int column = 1; column < max_col; column++)
|
||||
{
|
||||
source_location column_loc = loc + column;
|
||||
write_digit (stream, column_loc / divisor);
|
||||
}
|
||||
fprintf (stream, "\n");
|
||||
}
|
||||
|
||||
/* Write a half-closed (START) / half-open (END) interval of
|
||||
source_location to STREAM. */
|
||||
|
||||
static void
|
||||
dump_location_range (FILE *stream,
|
||||
source_location start, source_location end)
|
||||
{
|
||||
fprintf (stream,
|
||||
" source_location interval: %u <= loc < %u\n",
|
||||
start, end);
|
||||
}
|
||||
|
||||
/* Write a labelled description of a half-closed (START) / half-open (END)
|
||||
interval of source_location to STREAM. */
|
||||
|
||||
static void
|
||||
dump_labelled_location_range (FILE *stream,
|
||||
const char *name,
|
||||
source_location start, source_location end)
|
||||
{
|
||||
fprintf (stream, "%s\n", name);
|
||||
dump_location_range (stream, start, end);
|
||||
fprintf (stream, "\n");
|
||||
}
|
||||
|
||||
/* Write a visualization of the locations in the line_table to STREAM. */
|
||||
|
||||
void
|
||||
dump_location_info (FILE *stream)
|
||||
{
|
||||
/* Visualize the reserved locations. */
|
||||
dump_labelled_location_range (stream, "RESERVED LOCATIONS",
|
||||
0, RESERVED_LOCATION_COUNT);
|
||||
|
||||
/* Visualize the ordinary line_map instances, rendering the sources. */
|
||||
for (unsigned int idx = 0; idx < LINEMAPS_ORDINARY_USED (line_table); idx++)
|
||||
{
|
||||
source_location end_location = get_end_location (line_table, idx);
|
||||
/* half-closed: doesn't include this one. */
|
||||
|
||||
struct line_map *map = LINEMAPS_ORDINARY_MAP_AT (line_table, idx);
|
||||
fprintf (stream, "ORDINARY MAP: %i\n", idx);
|
||||
dump_location_range (stream,
|
||||
MAP_START_LOCATION (map), end_location);
|
||||
fprintf (stream, " file: %s\n", ORDINARY_MAP_FILE_NAME (map));
|
||||
fprintf (stream, " starting at line: %i\n",
|
||||
ORDINARY_MAP_STARTING_LINE_NUMBER (map));
|
||||
fprintf (stream, " column bits: %i\n",
|
||||
ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map));
|
||||
|
||||
/* Render the span of source lines that this "map" covers. */
|
||||
for (source_location loc = MAP_START_LOCATION (map);
|
||||
loc < end_location;
|
||||
loc++)
|
||||
{
|
||||
expanded_location exploc
|
||||
= linemap_expand_location (line_table, map, loc);
|
||||
|
||||
if (0 == exploc.column)
|
||||
{
|
||||
/* Beginning of a new source line: draw the line. */
|
||||
|
||||
int line_size;
|
||||
const char *line_text = location_get_source_line (exploc, &line_size);
|
||||
if (!line_text)
|
||||
break;
|
||||
fprintf (stream,
|
||||
"%s:%3i|loc:%5i|%.*s\n",
|
||||
exploc.file, exploc.line,
|
||||
loc,
|
||||
line_size, line_text);
|
||||
|
||||
/* "loc" is at column 0, which means "the whole line".
|
||||
Render the locations *within* the line, by underlining
|
||||
it, showing the source_location numeric values
|
||||
at each column. */
|
||||
int max_col
|
||||
= (1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)) - 1;
|
||||
if (max_col > line_size)
|
||||
max_col = line_size + 1;
|
||||
|
||||
int indent = 14 + strlen (exploc.file);
|
||||
|
||||
/* Thousands. */
|
||||
if (end_location > 999)
|
||||
write_digit_row (stream, indent, loc, max_col, 1000);
|
||||
|
||||
/* Hundreds. */
|
||||
if (end_location > 99)
|
||||
write_digit_row (stream, indent, loc, max_col, 100);
|
||||
|
||||
/* Tens. */
|
||||
write_digit_row (stream, indent, loc, max_col, 10);
|
||||
|
||||
/* Units. */
|
||||
write_digit_row (stream, indent, loc, max_col, 1);
|
||||
}
|
||||
}
|
||||
fprintf (stream, "\n");
|
||||
}
|
||||
|
||||
/* Visualize unallocated values. */
|
||||
dump_labelled_location_range (stream, "UNALLOCATED LOCATIONS",
|
||||
line_table->highest_location,
|
||||
LINEMAPS_MACRO_LOWEST_LOCATION (line_table));
|
||||
|
||||
/* Visualize the macro line_map instances, rendering the sources. */
|
||||
for (unsigned int i = 0; i < LINEMAPS_MACRO_USED (line_table); i++)
|
||||
{
|
||||
/* Each macro map that is allocated owns source_location values
|
||||
that are *lower* that the one before them.
|
||||
Hence it's meaningful to view them either in order of ascending
|
||||
source locations, or in order of ascending macro map index. */
|
||||
const bool ascending_source_locations = true;
|
||||
unsigned int idx = (ascending_source_locations
|
||||
? (LINEMAPS_MACRO_USED (line_table) - (i + 1))
|
||||
: i);
|
||||
struct line_map *map = LINEMAPS_MACRO_MAP_AT (line_table, idx);
|
||||
fprintf (stream, "MACRO %i: %s (%u tokens)\n",
|
||||
idx,
|
||||
linemap_map_get_macro_name (map),
|
||||
MACRO_MAP_NUM_MACRO_TOKENS (map));
|
||||
dump_location_range (stream,
|
||||
map->start_location,
|
||||
(map->start_location
|
||||
+ MACRO_MAP_NUM_MACRO_TOKENS (map)));
|
||||
inform (MACRO_MAP_EXPANSION_POINT_LOCATION (map),
|
||||
"expansion point is location %i",
|
||||
MACRO_MAP_EXPANSION_POINT_LOCATION (map));
|
||||
fprintf (stream, " map->start_location: %u\n",
|
||||
map->start_location);
|
||||
|
||||
fprintf (stream, " macro_locations:\n");
|
||||
for (unsigned int i = 0; i < MACRO_MAP_NUM_MACRO_TOKENS (map); i++)
|
||||
{
|
||||
source_location x = MACRO_MAP_LOCATIONS (map)[2 * i];
|
||||
source_location y = MACRO_MAP_LOCATIONS (map)[(2 * i) + 1];
|
||||
|
||||
/* linemap_add_macro_token encodes token numbers in an expansion
|
||||
by putting them after MAP_START_LOCATION. */
|
||||
|
||||
/* I'm typically seeing 4 uninitialized entries at the end of
|
||||
0xafafafaf.
|
||||
This appears to be due to macro.c:replace_args
|
||||
adding 2 extra args for padding tokens; presumably there may
|
||||
be a leading and/or trailing padding token injected,
|
||||
each for 2 more location slots.
|
||||
This would explain there being up to 4 source_locations slots
|
||||
that may be uninitialized. */
|
||||
|
||||
fprintf (stream, " %u: %u, %u\n",
|
||||
i,
|
||||
x,
|
||||
y);
|
||||
if (x == y)
|
||||
{
|
||||
if (x < MAP_START_LOCATION (map))
|
||||
inform (x, "token %u has x-location == y-location == %u", i, x);
|
||||
else
|
||||
fprintf (stream,
|
||||
"x-location == y-location == %u encodes token # %u\n",
|
||||
x, x - MAP_START_LOCATION (map));
|
||||
}
|
||||
else
|
||||
{
|
||||
inform (x, "token %u has x-location == %u", i, x);
|
||||
inform (x, "token %u has y-location == %u", i, y);
|
||||
}
|
||||
}
|
||||
fprintf (stream, "\n");
|
||||
}
|
||||
|
||||
/* It appears that MAX_SOURCE_LOCATION itself is never assigned to a
|
||||
macro map, presumably due to an off-by-one error somewhere
|
||||
between the logic in linemap_enter_macro and
|
||||
LINEMAPS_MACRO_LOWEST_LOCATION. */
|
||||
dump_labelled_location_range (stream, "MAX_SOURCE_LOCATION",
|
||||
MAX_SOURCE_LOCATION,
|
||||
MAX_SOURCE_LOCATION + 1);
|
||||
|
||||
/* Visualize ad-hoc values. */
|
||||
dump_labelled_location_range (stream, "AD-HOC LOCATIONS",
|
||||
MAX_SOURCE_LOCATION + 1, UINT_MAX);
|
||||
}
|
||||
|
@ -77,6 +77,8 @@ extern location_t input_location;
|
||||
|
||||
void dump_line_table_statistics (void);
|
||||
|
||||
void dump_location_info (FILE *stream);
|
||||
|
||||
void diagnostics_file_cache_fini (void);
|
||||
|
||||
#endif
|
||||
|
@ -593,6 +593,9 @@ compile_file (void)
|
||||
timevar_pop (TV_PARSE_GLOBAL);
|
||||
timevar_stop (TV_PHASE_PARSING);
|
||||
|
||||
if (flag_dump_locations)
|
||||
dump_location_info (stderr);
|
||||
|
||||
/* Compilation is now finished except for writing
|
||||
what's left of the symbol table output. */
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2015-05-13 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* include/line-map.h (source_location): Add a reference to
|
||||
location-example.txt to the descriptive comment.
|
||||
* location-example.txt: New file.
|
||||
|
||||
2015-05-13 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* include/line-map.h (MAX_SOURCE_LOCATION): Convert from a macro
|
||||
|
@ -113,7 +113,9 @@ typedef unsigned int linenum_type;
|
||||
... | |
|
||||
0xffffffff | UINT_MAX |
|
||||
-----------+-------------------------------+-------------------------------
|
||||
. */
|
||||
|
||||
To see how this works in practice, see the worked example in
|
||||
libcpp/location-example.txt. */
|
||||
typedef unsigned int source_location;
|
||||
|
||||
/* Memory allocation function typedef. Works like xrealloc. */
|
||||
|
216
libcpp/location-example.txt
Normal file
216
libcpp/location-example.txt
Normal file
@ -0,0 +1,216 @@
|
||||
Consider compiling test.c, with this content:
|
||||
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
|
||||
#include "test.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int a = PLUS (1,2);
|
||||
int b = PLUS (3,4);
|
||||
return 0;
|
||||
}
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
...where test.h has this content:
|
||||
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
|
||||
extern int foo ();
|
||||
|
||||
#define PLUS(A, B) A + B
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
The undocumented -fdump-internal-locations option outputs this information
|
||||
to stderr, showing what each source_location value means. Source code
|
||||
lines are quoted, showing both per-line source_location values and
|
||||
per-line&column source_location values (written vertically under the
|
||||
corresponding character of source code).
|
||||
|
||||
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
|
||||
RESERVED LOCATIONS
|
||||
source_location interval: 0 <= loc < 2
|
||||
|
||||
ORDINARY MAP: 0
|
||||
source_location interval: 2 <= loc < 3
|
||||
file: test.c
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
test.c: 1|loc: 2|#include "test.h"
|
||||
|00000001111111111
|
||||
|34567890123456789
|
||||
|
||||
ORDINARY MAP: 1
|
||||
source_location interval: 3 <= loc < 4
|
||||
file: <built-in>
|
||||
starting at line: 0
|
||||
column bits: 0
|
||||
|
||||
ORDINARY MAP: 2
|
||||
source_location interval: 4 <= loc < 5
|
||||
file: <command-line>
|
||||
starting at line: 0
|
||||
column bits: 0
|
||||
|
||||
ORDINARY MAP: 3
|
||||
source_location interval: 5 <= loc < 5005
|
||||
file: /usr/include/stdc-predef.h
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
(contents of /usr/include/stdc-predef.h snipped for brevity)
|
||||
|
||||
ORDINARY MAP: 4
|
||||
source_location interval: 5005 <= loc < 5006
|
||||
file: <command-line>
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
|
||||
ORDINARY MAP: 5
|
||||
source_location interval: 5006 <= loc < 5134
|
||||
file: test.c
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
test.c: 1|loc: 5006|#include "test.h"
|
||||
|55555555555555555
|
||||
|00000000000000000
|
||||
|00011111111112222
|
||||
|78901234567890123
|
||||
|
||||
ORDINARY MAP: 6
|
||||
source_location interval: 5134 <= loc < 5416
|
||||
file: test.h
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
test.h: 1|loc: 5134|extern int foo ();
|
||||
|555555555555555555
|
||||
|111111111111111111
|
||||
|333334444444444555
|
||||
|567890123456789012
|
||||
test.h: 2|loc: 5262|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
test.h: 3|loc: 5390|#define PLUS(A, B) A + B
|
||||
|555555555555555555555555
|
||||
|333333333444444444444444
|
||||
|999999999000000000011111
|
||||
|123456789012345678901234
|
||||
|
||||
ORDINARY MAP: 7
|
||||
source_location interval: 5416 <= loc < 6314
|
||||
file: test.c
|
||||
starting at line: 2
|
||||
column bits: 7
|
||||
test.c: 2|loc: 5416|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
test.c: 3|loc: 5544|int
|
||||
|555
|
||||
|555
|
||||
|444
|
||||
|567
|
||||
test.c: 4|loc: 5672|main (int argc, char **argv)
|
||||
|5555555555555555555555555555
|
||||
|6666666666666666666666666667
|
||||
|7777777888888888899999999990
|
||||
|3456789012345678901234567890
|
||||
test.c: 5|loc: 5800|{
|
||||
|5
|
||||
|8
|
||||
|0
|
||||
|1
|
||||
test.c: 6|loc: 5928| int a = PLUS (1,2);
|
||||
|555555555555555555555
|
||||
|999999999999999999999
|
||||
|233333333334444444444
|
||||
|901234567890123456789
|
||||
test.c: 7|loc: 6056| int b = PLUS (3,4);
|
||||
|666666666666666666666
|
||||
|000000000000000000000
|
||||
|555666666666677777777
|
||||
|789012345678901234567
|
||||
test.c: 8|loc: 6184| return 0;
|
||||
|66666666666
|
||||
|11111111111
|
||||
|88888999999
|
||||
|56789012345
|
||||
test.c: 9|loc: 6312|}
|
||||
|6
|
||||
|3
|
||||
|1
|
||||
|3
|
||||
|
||||
UNALLOCATED LOCATIONS
|
||||
source_location interval: 6314 <= loc < 2147483633
|
||||
|
||||
MACRO 1: PLUS (7 tokens)
|
||||
source_location interval: 2147483633 <= loc < 2147483640
|
||||
test.c:7:11: note: expansion point is location 6067
|
||||
int b = PLUS (3,4);
|
||||
^
|
||||
map->start_location: 2147483633
|
||||
macro_locations:
|
||||
0: 6073, 5410
|
||||
test.c:7:17: note: token 0 has x-location == 6073
|
||||
int b = PLUS (3,4);
|
||||
^
|
||||
test.c:7:17: note: token 0 has y-location == 5410
|
||||
1: 5412, 5412
|
||||
In file included from test.c:1:0:
|
||||
test.h:3:22: note: token 1 has x-location == y-location == 5412
|
||||
#define PLUS(A, B) A + B
|
||||
^
|
||||
2: 6075, 5414
|
||||
test.c:7:19: note: token 2 has x-location == 6075
|
||||
int b = PLUS (3,4);
|
||||
^
|
||||
test.c:7:19: note: token 2 has y-location == 5414
|
||||
3: 0, 2947526575
|
||||
cc1: note: token 3 has x-location == 0
|
||||
cc1: note: token 3 has y-location == 2947526575
|
||||
4: 2947526575, 2947526575
|
||||
x-location == y-location == 2947526575 encodes token # 800042942
|
||||
5: 2947526575, 2947526575
|
||||
x-location == y-location == 2947526575 encodes token # 800042942
|
||||
6: 2947526575, 2947526575
|
||||
x-location == y-location == 2947526575 encodes token # 800042942
|
||||
|
||||
MACRO 0: PLUS (7 tokens)
|
||||
source_location interval: 2147483640 <= loc < 2147483647
|
||||
test.c:6:11: note: expansion point is location 5939
|
||||
int a = PLUS (1,2);
|
||||
^
|
||||
map->start_location: 2147483640
|
||||
macro_locations:
|
||||
0: 5945, 5410
|
||||
test.c:6:17: note: token 0 has x-location == 5945
|
||||
int a = PLUS (1,2);
|
||||
^
|
||||
test.c:6:17: note: token 0 has y-location == 5410
|
||||
1: 5412, 5412
|
||||
In file included from test.c:1:0:
|
||||
test.h:3:22: note: token 1 has x-location == y-location == 5412
|
||||
#define PLUS(A, B) A + B
|
||||
^
|
||||
2: 5947, 5414
|
||||
test.c:6:19: note: token 2 has x-location == 5947
|
||||
int a = PLUS (1,2);
|
||||
^
|
||||
test.c:6:19: note: token 2 has y-location == 5414
|
||||
3: 0, 2947526575
|
||||
cc1: note: token 3 has x-location == 0
|
||||
cc1: note: token 3 has y-location == 2947526575
|
||||
4: 2947526575, 2947526575
|
||||
x-location == y-location == 2947526575 encodes token # 800042935
|
||||
5: 2947526575, 2947526575
|
||||
x-location == y-location == 2947526575 encodes token # 800042935
|
||||
6: 2947526575, 2947526575
|
||||
x-location == y-location == 2947526575 encodes token # 800042935
|
||||
|
||||
MAX_SOURCE_LOCATION
|
||||
source_location interval: 2147483647 <= loc < 2147483648
|
||||
|
||||
AD-HOC LOCATIONS
|
||||
source_location interval: 2147483648 <= loc < 4294967295
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
Loading…
Reference in New Issue
Block a user