static bool gfc_init (void) { if (!gfc_cpp_enabled ()) { linemap_add (line_table, LC_ENTER, false, gfc_source_file, 1); linemap_add (line_table, LC_RENAME, false, "<built-in>", 0); } else gfc_cpp_init_0 (); gfc_init_decl_processing (); gfc_static_ctors = NULL_TREE; if (gfc_cpp_enabled ()) gfc_cpp_init (); gfc_init_1 (); if (!gfc_new_file ()) fatal_error ("can't open input file: %s", gfc_source_file); if (flag_preprocess_only) return false; return true; }
source_location linemap_line_start (struct line_maps *set, linenum_type to_line, unsigned int max_column_hint) { struct line_map *map = &set->maps[set->used - 1]; 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 * map->column_bits > 1000) || (max_column_hint >= (1U << map->column_bits)) || (max_column_hint <= 80 && map->column_bits >= 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 != map->to_line || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) map = (struct line_map *) linemap_add (set, LC_RENAME, map->sysp, map->to_file, to_line); map->column_bits = column_bits; r = map->start_location + ((to_line - map->to_line) << column_bits); } else r = highest - SOURCE_COLUMN (map, highest) + (line_delta << map->column_bits); set->highest_line = r; if (r > set->highest_location) set->highest_location = r; set->max_column_hint = max_column_hint; return r; }
static gfc_file * get_file (char *name, enum lc_reason reason ATTRIBUTE_UNUSED) { gfc_file *f; f = gfc_getmem (sizeof (gfc_file)); f->filename = gfc_getmem (strlen (name) + 1); strcpy (f->filename, name); f->next = file_head; file_head = f; f->included_by = current_file; if (current_file != NULL) f->inclusion_line = current_file->line; #ifdef USE_MAPPED_LOCATION linemap_add (&line_table, reason, false, f->filename, 1); #endif return f; }
load_file (char *filename, bool initial) { char *line; gfc_linebuf *b; gfc_file *f; FILE *input; int len, line_len; for (f = current_file; f; f = f->up) if (strcmp (filename, f->filename) == 0) { gfc_error_now ("File '%s' is being included recursively", filename); return FAILURE; } if (initial) { input = gfc_open_file (filename); if (input == NULL) { gfc_error_now ("Can't open file '%s'", filename); return FAILURE; } } else { input = gfc_open_included_file (filename, false); if (input == NULL) { gfc_error_now ("Can't open included file '%s'", filename); return FAILURE; } } /* Load the file. */ f = get_file (filename, initial ? LC_RENAME : LC_ENTER); f->up = current_file; current_file = f; current_file->line = 1; line = NULL; line_len = 0; for (;;) { int trunc = load_line (input, &line, &line_len); len = strlen (line); if (feof (input) && len == 0) break; /* There are three things this line can be: a line of Fortran source, an include line or a C preprocessor directive. */ if (line[0] == '#') { preprocessor_line (line); continue; } if (include_line (line)) { current_file->line++; continue; } /* Add line. */ b = gfc_getmem (gfc_linebuf_header_size + len + 1); #ifdef USE_MAPPED_LOCATION b->location = linemap_line_start (&line_table, current_file->line++, 120); #else b->linenum = current_file->line++; #endif b->file = current_file; b->truncated = trunc; strcpy (b->line, line); if (line_head == NULL) line_head = b; else line_tail->next = b; line_tail = b; } /* Release the line buffer allocated in load_line. */ gfc_free (line); fclose (input); current_file = current_file->up; #ifdef USE_MAPPED_LOCATION linemap_add (&line_table, LC_LEAVE, 0, NULL, 0); #endif return SUCCESS; }
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; }