@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
23
23
#include "intl.h"
24
24
#include "input.h"
25
25
#include "vec.h"
26
+ #include "diagnostic-core.h"
26
27
27
28
/* This is a cache used by get_next_line to store the content of a
28
29
file to be searched for file lines. */
@@ -869,3 +870,226 @@ dump_line_table_statistics (void)
869
870
STAT_LABEL (total_used_map_size ));
870
871
fprintf (stderr , "\n" );
871
872
}
873
+
874
+ /* Get location one beyond the final location in ordinary map IDX. */
875
+
876
+ static source_location
877
+ get_end_location (struct line_maps * set , unsigned int idx )
878
+ {
879
+ if (idx == LINEMAPS_ORDINARY_USED (set ) - 1 )
880
+ return set -> highest_location ;
881
+
882
+ struct line_map * next_map = LINEMAPS_ORDINARY_MAP_AT (set , idx + 1 );
883
+ return MAP_START_LOCATION (next_map );
884
+ }
885
+
886
+ /* Helper function for write_digit_row. */
887
+
888
+ static void
889
+ write_digit (FILE * stream , int digit )
890
+ {
891
+ fputc ('0' + (digit % 10 ), stream );
892
+ }
893
+
894
+ /* Helper function for dump_location_info.
895
+ Write a row of numbers to STREAM, numbering a source line,
896
+ giving the units, tens, hundreds etc of the column number. */
897
+
898
+ static void
899
+ write_digit_row (FILE * stream , int indent ,
900
+ source_location loc , int max_col , int divisor )
901
+ {
902
+ fprintf (stream , "%*c" , indent , ' ' );
903
+ fprintf (stream , "|" );
904
+ for (int column = 1 ; column < max_col ; column ++ )
905
+ {
906
+ source_location column_loc = loc + column ;
907
+ write_digit (stream , column_loc / divisor );
908
+ }
909
+ fprintf (stream , "\n" );
910
+ }
911
+
912
+ /* Write a half-closed (START) / half-open (END) interval of
913
+ source_location to STREAM. */
914
+
915
+ static void
916
+ dump_location_range (FILE * stream ,
917
+ source_location start , source_location end )
918
+ {
919
+ fprintf (stream ,
920
+ " source_location interval: %u <= loc < %u\n" ,
921
+ start , end );
922
+ }
923
+
924
+ /* Write a labelled description of a half-closed (START) / half-open (END)
925
+ interval of source_location to STREAM. */
926
+
927
+ static void
928
+ dump_labelled_location_range (FILE * stream ,
929
+ const char * name ,
930
+ source_location start , source_location end )
931
+ {
932
+ fprintf (stream , "%s\n" , name );
933
+ dump_location_range (stream , start , end );
934
+ fprintf (stream , "\n" );
935
+ }
936
+
937
+ /* Write a visualization of the locations in the line_table to STREAM. */
938
+
939
+ void
940
+ dump_location_info (FILE * stream )
941
+ {
942
+ /* Visualize the reserved locations. */
943
+ dump_labelled_location_range (stream , "RESERVED LOCATIONS" ,
944
+ 0 , RESERVED_LOCATION_COUNT );
945
+
946
+ /* Visualize the ordinary line_map instances, rendering the sources. */
947
+ for (unsigned int idx = 0 ; idx < LINEMAPS_ORDINARY_USED (line_table ); idx ++ )
948
+ {
949
+ source_location end_location = get_end_location (line_table , idx );
950
+ /* half-closed: doesn't include this one. */
951
+
952
+ struct line_map * map = LINEMAPS_ORDINARY_MAP_AT (line_table , idx );
953
+ fprintf (stream , "ORDINARY MAP: %i\n" , idx );
954
+ dump_location_range (stream ,
955
+ MAP_START_LOCATION (map ), end_location );
956
+ fprintf (stream , " file: %s\n" , ORDINARY_MAP_FILE_NAME (map ));
957
+ fprintf (stream , " starting at line: %i\n" ,
958
+ ORDINARY_MAP_STARTING_LINE_NUMBER (map ));
959
+ fprintf (stream , " column bits: %i\n" ,
960
+ ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map ));
961
+
962
+ /* Render the span of source lines that this "map" covers. */
963
+ for (source_location loc = MAP_START_LOCATION (map );
964
+ loc < end_location ;
965
+ loc ++ )
966
+ {
967
+ expanded_location exploc
968
+ = linemap_expand_location (line_table , map , loc );
969
+
970
+ if (0 == exploc .column )
971
+ {
972
+ /* Beginning of a new source line: draw the line. */
973
+
974
+ int line_size ;
975
+ const char * line_text = location_get_source_line (exploc , & line_size );
976
+ if (!line_text )
977
+ break ;
978
+ fprintf (stream ,
979
+ "%s:%3i|loc:%5i|%.*s\n" ,
980
+ exploc .file , exploc .line ,
981
+ loc ,
982
+ line_size , line_text );
983
+
984
+ /* "loc" is at column 0, which means "the whole line".
985
+ Render the locations *within* the line, by underlining
986
+ it, showing the source_location numeric values
987
+ at each column. */
988
+ int max_col
989
+ = (1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map )) - 1 ;
990
+ if (max_col > line_size )
991
+ max_col = line_size + 1 ;
992
+
993
+ int indent = 14 + strlen (exploc .file );
994
+
995
+ /* Thousands. */
996
+ if (end_location > 999 )
997
+ write_digit_row (stream , indent , loc , max_col , 1000 );
998
+
999
+ /* Hundreds. */
1000
+ if (end_location > 99 )
1001
+ write_digit_row (stream , indent , loc , max_col , 100 );
1002
+
1003
+ /* Tens. */
1004
+ write_digit_row (stream , indent , loc , max_col , 10 );
1005
+
1006
+ /* Units. */
1007
+ write_digit_row (stream , indent , loc , max_col , 1 );
1008
+ }
1009
+ }
1010
+ fprintf (stream , "\n" );
1011
+ }
1012
+
1013
+ /* Visualize unallocated values. */
1014
+ dump_labelled_location_range (stream , "UNALLOCATED LOCATIONS" ,
1015
+ line_table -> highest_location ,
1016
+ LINEMAPS_MACRO_LOWEST_LOCATION (line_table ));
1017
+
1018
+ /* Visualize the macro line_map instances, rendering the sources. */
1019
+ for (unsigned int i = 0 ; i < LINEMAPS_MACRO_USED (line_table ); i ++ )
1020
+ {
1021
+ /* Each macro map that is allocated owns source_location values
1022
+ that are *lower* that the one before them.
1023
+ Hence it's meaningful to view them either in order of ascending
1024
+ source locations, or in order of ascending macro map index. */
1025
+ const bool ascending_source_locations = true;
1026
+ unsigned int idx = (ascending_source_locations
1027
+ ? (LINEMAPS_MACRO_USED (line_table ) - (i + 1 ))
1028
+ : i );
1029
+ struct line_map * map = LINEMAPS_MACRO_MAP_AT (line_table , idx );
1030
+ fprintf (stream , "MACRO %i: %s (%u tokens)\n" ,
1031
+ idx ,
1032
+ linemap_map_get_macro_name (map ),
1033
+ MACRO_MAP_NUM_MACRO_TOKENS (map ));
1034
+ dump_location_range (stream ,
1035
+ map -> start_location ,
1036
+ (map -> start_location
1037
+ + MACRO_MAP_NUM_MACRO_TOKENS (map )));
1038
+ inform (MACRO_MAP_EXPANSION_POINT_LOCATION (map ),
1039
+ "expansion point is location %i" ,
1040
+ MACRO_MAP_EXPANSION_POINT_LOCATION (map ));
1041
+ fprintf (stream , " map->start_location: %u\n" ,
1042
+ map -> start_location );
1043
+
1044
+ fprintf (stream , " macro_locations:\n" );
1045
+ for (unsigned int i = 0 ; i < MACRO_MAP_NUM_MACRO_TOKENS (map ); i ++ )
1046
+ {
1047
+ source_location x = MACRO_MAP_LOCATIONS (map )[2 * i ];
1048
+ source_location y = MACRO_MAP_LOCATIONS (map )[(2 * i ) + 1 ];
1049
+
1050
+ /* linemap_add_macro_token encodes token numbers in an expansion
1051
+ by putting them after MAP_START_LOCATION. */
1052
+
1053
+ /* I'm typically seeing 4 uninitialized entries at the end of
1054
+ 0xafafafaf.
1055
+ This appears to be due to macro.c:replace_args
1056
+ adding 2 extra args for padding tokens; presumably there may
1057
+ be a leading and/or trailing padding token injected,
1058
+ each for 2 more location slots.
1059
+ This would explain there being up to 4 source_locations slots
1060
+ that may be uninitialized. */
1061
+
1062
+ fprintf (stream , " %u: %u, %u\n" ,
1063
+ i ,
1064
+ x ,
1065
+ y );
1066
+ if (x == y )
1067
+ {
1068
+ if (x < MAP_START_LOCATION (map ))
1069
+ inform (x , "token %u has x-location == y-location == %u" , i , x );
1070
+ else
1071
+ fprintf (stream ,
1072
+ "x-location == y-location == %u encodes token # %u\n" ,
1073
+ x , x - MAP_START_LOCATION (map ));
1074
+ }
1075
+ else
1076
+ {
1077
+ inform (x , "token %u has x-location == %u" , i , x );
1078
+ inform (x , "token %u has y-location == %u" , i , y );
1079
+ }
1080
+ }
1081
+ fprintf (stream , "\n" );
1082
+ }
1083
+
1084
+ /* It appears that MAX_SOURCE_LOCATION itself is never assigned to a
1085
+ macro map, presumably due to an off-by-one error somewhere
1086
+ between the logic in linemap_enter_macro and
1087
+ LINEMAPS_MACRO_LOWEST_LOCATION. */
1088
+ dump_labelled_location_range (stream , "MAX_SOURCE_LOCATION" ,
1089
+ MAX_SOURCE_LOCATION ,
1090
+ MAX_SOURCE_LOCATION + 1 );
1091
+
1092
+ /* Visualize ad-hoc values. */
1093
+ dump_labelled_location_range (stream , "AD-HOC LOCATIONS" ,
1094
+ MAX_SOURCE_LOCATION + 1 , UINT_MAX );
1095
+ }
0 commit comments