void linemap_print_containing_files (struct line_maps *set, const struct line_map *map) { if (MAIN_FILE_P (map) || set->last_listed == map->included_from) return; set->last_listed = map->included_from; map = INCLUDED_FROM (set, map); fprintf (stderr, _("In file included from %s:%u"), map->to_file, LAST_SOURCE_LINE (map)); while (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (set, map); /* Translators note: this message is used in conjunction with "In file included from %s:%ld" and some other tricks. We want something like this: | In file included from sys/select.h:123, | from sys/types.h:234, | from userfile.c:31: | bits/select.h:45: <error message here> with all the "from"s lined up. The trailing comma is at the beginning of this message, and the trailing colon is not translated. */ fprintf (stderr, _(",\n from %s:%u"), map->to_file, LAST_SOURCE_LINE (map)); } fputs (":\n", stderr); }
void diagnostic_report_current_module (diagnostic_context *context, location_t where) { const struct line_map *map = NULL; if (pp_needs_newline (context->printer)) { pp_newline (context->printer); pp_needs_newline (context->printer) = false; } if (where <= BUILTINS_LOCATION) return; linemap_resolve_location (line_table, where, LRK_MACRO_DEFINITION_LOCATION, &map); if (map && diagnostic_last_module_changed (context, map)) { diagnostic_set_last_module (context, map); if (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (line_table, map); if (context->show_column) pp_verbatim (context->printer, "In file included from %s:%d:%d", LINEMAP_FILE (map), LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map)); else pp_verbatim (context->printer, "In file included from %s:%d", LINEMAP_FILE (map), LAST_SOURCE_LINE (map)); while (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (line_table, map); pp_verbatim (context->printer, ",\n from %s:%d", LINEMAP_FILE (map), LAST_SOURCE_LINE (map)); } pp_verbatim (context->printer, ":"); pp_newline (context->printer); } } }
void diagnostic_report_current_module (diagnostic_context *context) { const struct line_map *map; if (pp_needs_newline (context->printer)) { pp_newline (context->printer); pp_needs_newline (context->printer) = false; } if (input_location <= BUILTINS_LOCATION) return; map = linemap_lookup (line_table, input_location); if (map && diagnostic_last_module_changed (context, map)) { diagnostic_set_last_module (context, map); if (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (line_table, map); if (flag_show_column) pp_verbatim (context->printer, "In file included from %s:%d:%d", map->to_file, LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map)); else pp_verbatim (context->printer, "In file included from %s:%d", map->to_file, LAST_SOURCE_LINE (map)); while (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (line_table, map); pp_verbatim (context->printer, ",\n from %s:%d", map->to_file, LAST_SOURCE_LINE (map)); } pp_verbatim (context->printer, ":"); pp_newline (context->printer); } } }
void linemap_check_files_exited (struct line_maps *set) { struct line_map *map; /* Depending upon whether we are handling preprocessed input or not, this can be a user error or an ICE. */ for (map = &set->maps[set->used - 1]; ! MAIN_FILE_P (map); map = INCLUDED_FROM (set, map)) fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n", map->to_file); }
void linemap_check_files_exited (struct line_maps *set) { struct line_map *map; /* Depending upon whether we are handling preprocessed input or not, this can be a user error or an ICE. */ for (map = LINEMAPS_LAST_ORDINARY_MAP (set); ! MAIN_FILE_P (map); map = INCLUDED_FROM (set, map)) fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n", ORDINARY_MAP_FILE_NAME (map)); }
void linemap_dump_location (struct line_maps *set, source_location loc, FILE *stream) { const struct line_map *map; source_location location; const char *path = "", *from = ""; int l = -1, c = -1, s = -1, e = -1; if (loc == 0) return; location = linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map); if (map == NULL) /* Only reserved locations can be tolerated in this case. */ linemap_assert (location < RESERVED_LOCATION_COUNT); else { path = LINEMAP_FILE (map); l = SOURCE_LINE (map, location); c = SOURCE_COLUMN (map, location); s = LINEMAP_SYSP (map) != 0; e = location != loc; if (e) from = "N/A"; else from = (INCLUDED_FROM (set, map)) ? LINEMAP_FILE (INCLUDED_FROM (set, map)) : "<NULL>"; } /* P: path, L: line, C: column, S: in-system-header, M: map address, E: macro expansion?, LOC: original location, R: resolved location */ fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}", path, from, l, c, s, (void*)map, e, loc, location); }
const struct line_map * linemap_add (struct line_maps *set, enum lc_reason reason, unsigned int sysp, const char *to_file, linenum_type to_line) { struct line_map *map; source_location start_location = set->highest_location + 1; if (set->used && start_location < set->maps[set->used - 1].start_location) abort (); if (set->used == set->allocated) { line_map_realloc reallocator = set->reallocator ? set->reallocator : xrealloc; set->allocated = 2 * set->allocated + 256; set->maps = (struct line_map *) (*reallocator) (set->maps, set->allocated * sizeof (struct line_map)); memset (&set->maps[set->used], 0, ((set->allocated - set->used) * sizeof (struct line_map))); } map = &set->maps[set->used]; if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM) to_file = "<stdin>"; if (reason == LC_RENAME_VERBATIM) reason = LC_RENAME; /* If we don't keep our line maps consistent, we can easily segfault. Don't rely on the client to do it for us. */ if (set->depth == 0) reason = LC_ENTER; else if (reason == LC_LEAVE) { struct line_map *from; bool error; if (MAIN_FILE_P (map - 1)) { if (to_file == NULL) { set->depth--; return NULL; } error = true; reason = LC_RENAME; from = map - 1; } else { from = INCLUDED_FROM (set, map - 1); error = to_file && strcmp (from->to_file, to_file); } /* Depending upon whether we are handling preprocessed input or not, this can be a user error or an ICE. */ if (error) fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n", to_file); /* A TO_FILE of NULL is special - we use the natural values. */ if (error || to_file == NULL) { to_file = from->to_file; to_line = SOURCE_LINE (from, from[1].start_location); sysp = from->sysp; } } map->reason = reason; map->sysp = sysp; map->start_location = start_location; map->to_file = to_file; map->to_line = to_line; set->cache = set->used++; map->column_bits = 0; set->highest_location = start_location; set->highest_line = start_location; set->max_column_hint = 0; if (reason == LC_ENTER) { map->included_from = set->depth == 0 ? -1 : (int) (set->used - 2); set->depth++; if (set->trace_includes) trace_include (set, map); } else if (reason == LC_RENAME) map->included_from = map[-1].included_from; else if (reason == LC_LEAVE) { set->depth--; map->included_from = INCLUDED_FROM (set, map - 1)->included_from; } return map; }
const struct line_map * linemap_add (struct line_maps *set, enum lc_reason reason, unsigned int sysp, const char *to_file, linenum_type to_line) { struct line_map *map; source_location start_location = set->highest_location + 1; linemap_assert (!(LINEMAPS_ORDINARY_USED (set) && (start_location < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))))); /* When we enter the file for the first time reason cannot be LC_RENAME. */ linemap_assert (!(set->depth == 0 && reason == LC_RENAME)); /* If we are leaving the main file, return a NULL map. */ if (reason == LC_LEAVE && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set)) && to_file == NULL) { set->depth--; return NULL; } map = new_linemap (set, reason); if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM) to_file = "<stdin>"; if (reason == LC_RENAME_VERBATIM) reason = LC_RENAME; if (reason == LC_LEAVE) { /* When we are just leaving an "included" file, and jump to the next location inside the "includer" right after the #include "included", this variable points the map in use right before the #include "included", inside the same "includer" file. */ struct line_map *from; bool error; if (MAIN_FILE_P (map - 1)) { /* So this _should_ means we are leaving the main file -- effectively ending the compilation unit. But to_file not being NULL means the caller thinks we are leaving to another file. This is an erroneous behaviour but we'll try to recover from it. Let's pretend we are not leaving the main file. */ error = true; reason = LC_RENAME; from = map - 1; } else { /* (MAP - 1) points to the map we are leaving. The map from which (MAP - 1) got included should be the map that comes right before MAP in the same file. */ from = INCLUDED_FROM (set, map - 1); error = to_file && filename_cmp (ORDINARY_MAP_FILE_NAME (from), to_file); } /* Depending upon whether we are handling preprocessed input or not, this can be a user error or an ICE. */ if (error) fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n", to_file); /* A TO_FILE of NULL is special - we use the natural values. */ if (error || to_file == NULL) { to_file = ORDINARY_MAP_FILE_NAME (from); to_line = SOURCE_LINE (from, from[1].start_location); sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from); } } linemap_assert (reason != LC_ENTER_MACRO); ORDINARY_MAP_IN_SYSTEM_HEADER_P (map) = sysp; MAP_START_LOCATION (map) = start_location; ORDINARY_MAP_FILE_NAME (map) = to_file; ORDINARY_MAP_STARTING_LINE_NUMBER (map) = to_line; LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1; ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) = 0; set->highest_location = start_location; set->highest_line = start_location; set->max_column_hint = 0; if (reason == LC_ENTER) { ORDINARY_MAP_INCLUDER_FILE_INDEX (map) = set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2); set->depth++; if (set->trace_includes) trace_include (set, map); } else if (reason == LC_RENAME) ORDINARY_MAP_INCLUDER_FILE_INDEX (map) = ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]); else if (reason == LC_LEAVE) { set->depth--; ORDINARY_MAP_INCLUDER_FILE_INDEX (map) = ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1)); } return map; }