/* Setup for processing input from the file named FNAME, or stdin if it is the empty string. Return the original filename on success (e.g. foo.i->foo.c), or NULL on failure. */ const char * cpp_read_main_file (cpp_reader *pfile, const char *fname) { if (CPP_OPTION (pfile, deps.style) != DEPS_NONE) { if (!pfile->deps) pfile->deps = deps_init (); /* Set the default target (if there is none already). */ deps_add_default_target (pfile->deps, fname); } pfile->main_file = _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0); if (_cpp_find_failed (pfile->main_file)) return NULL; _cpp_stack_file (pfile, pfile->main_file, false); /* For foo.i, read the original filename foo.c now, for the benefit of the front ends. */ if (CPP_OPTION (pfile, preprocessed)) { read_original_filename (pfile); fname = ORDINARY_MAP_FILE_NAME ((LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table))); } return fname; }
void linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro) { const char *lc_reasons_v[LC_ENTER_MACRO + 1] = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM", "LC_ENTER_MACRO" }; const char *reason; struct line_map *map; if (stream == NULL) stream = stderr; if (!is_macro) map = LINEMAPS_ORDINARY_MAP_AT (set, ix); else map = LINEMAPS_MACRO_MAP_AT (set, ix); reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???"; fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n", ix, (void *) map, map->start_location, reason, (!is_macro && ORDINARY_MAP_IN_SYSTEM_HEADER_P (map)) ? "yes" : "no"); if (!is_macro) { unsigned includer_ix; struct line_map *includer_map; includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (map); includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set) ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix) : NULL; fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (map), ORDINARY_MAP_STARTING_LINE_NUMBER (map)); fprintf (stream, "Included from: [%d] %s\n", includer_ix, includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None"); } else fprintf (stream, "Macro: %s (%u tokens)\n", linemap_map_get_macro_name (map), MACRO_MAP_NUM_MACRO_TOKENS (map)); fprintf (stream, "\n"); }
static void trace_include (const struct line_maps *set, const struct line_map *map) { unsigned int i = set->depth; while (--i) putc ('.', stderr); fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map)); }
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)); }
source_location linemap_line_start (struct line_maps *set, linenum_type to_line, unsigned int max_column_hint) { struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (set); source_location highest = set->highest_location; source_location r; linenum_type last_line = SOURCE_LINE (map, set->highest_line); int line_delta = to_line - last_line; bool add_map = false; if (line_delta < 0 || (line_delta > 10 && line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000) || (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map))) || (max_column_hint <= 80 && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10)) { add_map = true; } else max_column_hint = set->max_column_hint; if (add_map) { int column_bits; if (max_column_hint > 100000 || highest > 0xC0000000) { /* If the column number is ridiculous or we've allocated a huge number of source_locations, give up on column numbers. */ max_column_hint = 0; if (highest >0xF0000000) return 0; column_bits = 0; } else { column_bits = 7; while (max_column_hint >= (1U << column_bits)) column_bits++; max_column_hint = 1U << column_bits; } /* Allocate the new line_map. However, if the current map only has a single line we can sometimes just increase its column_bits instead. */ if (line_delta < 0 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) map = (struct line_map *) linemap_add (set, LC_RENAME, ORDINARY_MAP_IN_SYSTEM_HEADER_P (map), ORDINARY_MAP_FILE_NAME (map), to_line); ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) = column_bits; r = (MAP_START_LOCATION (map) + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) << column_bits)); } else r = highest - SOURCE_COLUMN (map, highest) + (line_delta << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)); /* Locations of ordinary tokens are always lower than locations of macro tokens. */ if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set)) return 0; set->highest_line = r; if (r > set->highest_location) set->highest_location = r; set->max_column_hint = max_column_hint; return r; }
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; }