LCOV - code coverage report
Current view: top level - gcc/fortran - scanner.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.9 % 1369 1340
Test Date: 2026-04-20 14:57:17 Functions: 100.0 % 62 62
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Character scanner.
       2              :    Copyright (C) 2000-2026 Free Software Foundation, Inc.
       3              :    Contributed by Andy Vaught
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : /* Set of subroutines to (ultimately) return the next character to the
      22              :    various matching subroutines.  This file's job is to read files and
      23              :    build up lines that are parsed by the parser.  This means that we
      24              :    handle continuation lines and "include" lines.
      25              : 
      26              :    The first thing the scanner does is to load an entire file into
      27              :    memory.  We load the entire file into memory for a couple reasons.
      28              :    The first is that we want to be able to deal with nonseekable input
      29              :    (pipes, stdin) and there is a lot of backing up involved during
      30              :    parsing.
      31              : 
      32              :    The second is that we want to be able to print the locus of errors,
      33              :    and an error on line 999999 could conflict with something on line
      34              :    one.  Given nonseekable input, we've got to store the whole thing.
      35              : 
      36              :    One thing that helps are the column truncation limits that give us
      37              :    an upper bound on the size of individual lines.  We don't store the
      38              :    truncated stuff.
      39              : 
      40              :    From the scanner's viewpoint, the higher level subroutines ask for
      41              :    new characters and do a lot of jumping backwards.  */
      42              : 
      43              : #include "config.h"
      44              : #include "system.h"
      45              : #include "coretypes.h"
      46              : #include "gfortran.h"
      47              : #include "toplev.h"   /* For set_src_pwd.  */
      48              : #include "debug.h"
      49              : #include "options.h"
      50              : #include "diagnostic-core.h"  /* For fatal_error. */
      51              : #include "cpp.h"
      52              : #include "scanner.h"
      53              : 
      54              : /* List of include file search directories.  */
      55              : gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
      56              : 
      57              : static gfc_file *file_head, *current_file;
      58              : 
      59              : static bool continue_flag, end_flag, gcc_attribute_flag;
      60              : /* If !$omp/!$acc occurred in current comment line.  */
      61              : static int openmp_flag, openacc_flag;
      62              : static int continue_count, continue_line;
      63              : static locus openmp_locus;
      64              : static locus openacc_locus;
      65              : static locus gcc_attribute_locus;
      66              : 
      67              : gfc_source_form gfc_current_form;
      68              : static gfc_linebuf *line_head, *line_tail;
      69              : 
      70              : locus gfc_current_locus;
      71              : const char *gfc_source_file;
      72              : static FILE *gfc_src_file;
      73              : static gfc_char_t *gfc_src_preprocessor_lines[2];
      74              : 
      75              : static struct gfc_file_change
      76              : {
      77              :   const char *filename;
      78              :   gfc_linebuf *lb;
      79              :   int line;
      80              : } *file_changes;
      81              : static size_t file_changes_cur, file_changes_count;
      82              : static size_t file_changes_allocated;
      83              : 
      84              : static gfc_char_t *last_error_char;
      85              : 
      86              : /* Functions dealing with our wide characters (gfc_char_t) and
      87              :    sequences of such characters.  */
      88              : 
      89              : bool
      90   1348203011 : gfc_wide_fits_in_byte (gfc_char_t c)
      91              : {
      92   1348203011 :   return (c <= UCHAR_MAX);
      93              : }
      94              : 
      95              : static inline int
      96    682948851 : wide_is_ascii (gfc_char_t c)
      97              : {
      98    682948851 :   return (gfc_wide_fits_in_byte (c) && ((unsigned char) c & ~0x7f) == 0);
      99              : }
     100              : 
     101              : bool
     102        30117 : gfc_wide_is_printable (gfc_char_t c)
     103              : {
     104        30117 :   return (gfc_wide_fits_in_byte (c) && ISPRINT ((unsigned char) c));
     105              : }
     106              : 
     107              : gfc_char_t
     108    682817110 : gfc_wide_tolower (gfc_char_t c)
     109              : {
     110    682817110 :   return (wide_is_ascii (c) ? (gfc_char_t) TOLOWER((unsigned char) c) : c);
     111              : }
     112              : 
     113              : gfc_char_t
     114       131741 : gfc_wide_toupper (gfc_char_t c)
     115              : {
     116       131741 :   return (wide_is_ascii (c) ? (gfc_char_t) TOUPPER((unsigned char) c) : c);
     117              : }
     118              : 
     119              : bool
     120     12541963 : gfc_wide_is_digit (gfc_char_t c)
     121              : {
     122     12541963 :   return (c >= '0' && c <= '9');
     123              : }
     124              : 
     125              : static inline int
     126        13200 : wide_atoi (gfc_char_t *c)
     127              : {
     128              : #define MAX_DIGITS 20
     129        13200 :   char buf[MAX_DIGITS+1];
     130        13200 :   int i = 0;
     131              : 
     132        28582 :   while (gfc_wide_is_digit(*c) && i < MAX_DIGITS)
     133        15382 :     buf[i++] = *c++;
     134        13200 :   buf[i] = '\0';
     135        13200 :   return atoi (buf);
     136              : }
     137              : 
     138              : size_t
     139      6814347 : gfc_wide_strlen (const gfc_char_t *str)
     140              : {
     141      6814347 :   size_t i;
     142              : 
     143    304773365 :   for (i = 0; str[i]; i++)
     144              :     ;
     145              : 
     146      6814347 :   return i;
     147              : }
     148              : 
     149              : gfc_char_t *
     150       347594 : gfc_wide_memset (gfc_char_t *b, gfc_char_t c, size_t len)
     151              : {
     152       347594 :   size_t i;
     153              : 
     154      3086936 :   for (i = 0; i < len; i++)
     155      2739342 :     b[i] = c;
     156              : 
     157       347594 :   return b;
     158              : }
     159              : 
     160              : static gfc_char_t *
     161      6725070 : wide_strcpy (gfc_char_t *dest, const gfc_char_t *src)
     162              : {
     163      6725070 :   gfc_char_t *d;
     164              : 
     165    303714232 :   for (d = dest; (*d = *src) != '\0'; ++src, ++d)
     166              :     ;
     167              : 
     168      6725070 :   return dest;
     169              : }
     170              : 
     171              : static gfc_char_t *
     172            0 : wide_strchr (const gfc_char_t *s, gfc_char_t c)
     173              : {
     174        37521 :   do {
     175        37521 :     if (*s == c)
     176              :       return const_cast<gfc_char_t *> (s);
     177        24321 :   } while (*s++);
     178              :   return 0;
     179              : }
     180              : 
     181              : char *
     182        10612 : gfc_widechar_to_char (const gfc_char_t *s, int length)
     183              : {
     184        10612 :   size_t len, i;
     185        10612 :   char *res;
     186              : 
     187        10612 :   if (s == NULL)
     188              :     return NULL;
     189              : 
     190              :   /* Passing a negative length is used to indicate that length should be
     191              :      calculated using gfc_wide_strlen().  */
     192        10612 :   len = (length >= 0 ? (size_t) length : gfc_wide_strlen (s));
     193        10612 :   res = XNEWVEC (char, len + 1);
     194              : 
     195       459166 :   for (i = 0; i < len; i++)
     196              :     {
     197       437942 :       gcc_assert (gfc_wide_fits_in_byte (s[i]));
     198       437942 :       res[i] = (unsigned char) s[i];
     199              :     }
     200              : 
     201        10612 :   res[len] = '\0';
     202        10612 :   return res;
     203              : }
     204              : 
     205              : gfc_char_t *
     206         2647 : gfc_char_to_widechar (const char *s)
     207              : {
     208         2647 :   size_t len, i;
     209         2647 :   gfc_char_t *res;
     210              : 
     211         2647 :   if (s == NULL)
     212              :     return NULL;
     213              : 
     214         2647 :   len = strlen (s);
     215         2647 :   res = gfc_get_wide_string (len + 1);
     216              : 
     217        44102 :   for (i = 0; i < len; i++)
     218        38808 :     res[i] = (unsigned char) s[i];
     219              : 
     220         2647 :   res[len] = '\0';
     221         2647 :   return res;
     222              : }
     223              : 
     224              : static int
     225           87 : wide_strncmp (const gfc_char_t *s1, const char *s2, size_t n)
     226              : {
     227           87 :   gfc_char_t c1, c2;
     228              : 
     229          320 :   while (n-- > 0)
     230              :     {
     231          294 :       c1 = *s1++;
     232          294 :       c2 = *s2++;
     233          294 :       if (c1 != c2)
     234          116 :         return (c1 > c2 ? 1 : -1);
     235          233 :       if (c1 == '\0')
     236              :         return 0;
     237              :     }
     238              :   return 0;
     239              : }
     240              : 
     241              : int
     242      6389749 : gfc_wide_strncasecmp (const gfc_char_t *s1, const char *s2, size_t n)
     243              : {
     244      6389749 :   gfc_char_t c1, c2;
     245              : 
     246      6910609 :   while (n-- > 0)
     247              :     {
     248      6901762 :       c1 = gfc_wide_tolower (*s1++);
     249      6901762 :       c2 = TOLOWER (*s2++);
     250      6901762 :       if (c1 != c2)
     251     12229170 :         return (c1 > c2 ? 1 : -1);
     252       520860 :       if (c1 == '\0')
     253              :         return 0;
     254              :     }
     255              :   return 0;
     256              : }
     257              : 
     258              : 
     259              : /* Main scanner initialization.  */
     260              : 
     261              : void
     262        31441 : gfc_scanner_init_1 (void)
     263              : {
     264        31441 :   file_head = NULL;
     265        31441 :   line_head = NULL;
     266        31441 :   line_tail = NULL;
     267              : 
     268        31441 :   continue_count = 0;
     269        31441 :   continue_line = 0;
     270              : 
     271        31441 :   end_flag = 0;
     272        31441 :   last_error_char = NULL;
     273        31441 : }
     274              : 
     275              : 
     276              : /* Main scanner destructor.  */
     277              : 
     278              : void
     279        31422 : gfc_scanner_done_1 (void)
     280              : {
     281        31422 :   gfc_linebuf *lb;
     282        31422 :   gfc_file *f;
     283              : 
     284      6753812 :   while(line_head != NULL)
     285              :     {
     286      6722390 :       lb = line_head->next;
     287      6722390 :       free (line_head);
     288      6722390 :       line_head = lb;
     289              :     }
     290              : 
     291        96731 :   while(file_head != NULL)
     292              :     {
     293        65309 :       f = file_head->next;
     294        65309 :       free (file_head->filename);
     295        65309 :       free (file_head);
     296        65309 :       file_head = f;
     297              :     }
     298        31422 : }
     299              : 
     300              : static bool
     301       123779 : gfc_do_check_include_dir (const char *path, bool warn)
     302              : {
     303       123779 :   struct stat st;
     304       123779 :   if (stat (path, &st))
     305              :     {
     306        62857 :       if (errno != ENOENT)
     307            0 :         gfc_warning_now (0, "Include directory %qs: %s",
     308              :                          path, xstrerror(errno));
     309        62857 :       else if (warn)
     310           14 :           gfc_warning_now (OPT_Wmissing_include_dirs,
     311              :                            "Nonexistent include directory %qs", path);
     312        62857 :       return false;
     313              :     }
     314        60922 :   else if (!S_ISDIR (st.st_mode))
     315              :     {
     316            1 :       gfc_fatal_error ("%qs is not a directory", path);
     317              :       return false;
     318              :     }
     319              :   return true;
     320              : }
     321              : 
     322              : /* In order that -W(no-)missing-include-dirs works, the diagnostic can only be
     323              :    run after processing the commandline.  */
     324              : static void
     325        62886 : gfc_do_check_include_dirs (gfc_directorylist **list, bool do_warn)
     326              : {
     327        62886 :   gfc_directorylist *prev, *q, *n;
     328        62886 :   prev = NULL;
     329        62886 :   n = *list;
     330       120039 :   while (n)
     331              :     {
     332        57154 :       q = n; n = n->next;
     333        96100 :       if (gfc_do_check_include_dir (q->path, q->warn && do_warn))
     334              :         {
     335        25719 :           prev = q;
     336        25719 :           continue;
     337              :         }
     338        31434 :       if (prev == NULL)
     339        26858 :         *list = n;
     340              :       else
     341         4576 :         prev->next = n;
     342        31434 :       free (q->path);
     343        31434 :       free (q);
     344              :     }
     345        62885 : }
     346              : 
     347              : void
     348        31442 : gfc_check_include_dirs (bool verbose_missing_dir_warn)
     349              : {
     350              :   /* This is a bit convoluted: If gfc_cpp_enabled () and
     351              :      verbose_missing_dir_warn, the warning is shown by libcpp. Otherwise,
     352              :      it is shown here, still conditional on OPT_Wmissing_include_dirs.  */
     353        31442 :   bool warn = !gfc_cpp_enabled () || !verbose_missing_dir_warn;
     354        31442 :   gfc_do_check_include_dirs (&include_dirs, warn);
     355        31441 :   gfc_do_check_include_dirs (&intrinsic_modules_dirs, verbose_missing_dir_warn);
     356        31441 :   if (gfc_option.module_dir && gfc_cpp_enabled ())
     357            3 :     gfc_do_check_include_dirs (&include_dirs, true);
     358        31441 : }
     359              : 
     360              : /* Adds path to the list pointed to by list.  */
     361              : 
     362              : static void
     363       120017 : add_path_to_list (gfc_directorylist **list, const char *path,
     364              :                   bool use_for_modules, bool head, bool warn, bool defer_warn)
     365              : {
     366       120017 :   gfc_directorylist *dir;
     367       120017 :   const char *p;
     368       120017 :   char *q;
     369       120017 :   size_t len;
     370       120017 :   int i;
     371              : 
     372       120017 :   p = path;
     373       120017 :   while (*p == ' ' || *p == '\t')  /* someone might do "-I include" */
     374            0 :     if (*p++ == '\0')
     375              :       return;
     376              : 
     377              :   /* Strip trailing directory separators from the path, as this
     378              :      will confuse Windows systems.  */
     379       120017 :   len = strlen (p);
     380       120017 :   q = (char *) alloca (len + 1);
     381       120017 :   memcpy (q, p, len + 1);
     382       120017 :   i = len - 1;
     383       120544 :   while (i >=0 && IS_DIR_SEPARATOR (q[i]))
     384          527 :     q[i--] = '\0';
     385              : 
     386       120017 :   if (!defer_warn && !gfc_do_check_include_dir (q, warn))
     387              :     return;
     388              : 
     389        88594 :   if (head || *list == NULL)
     390              :     {
     391        66623 :       dir = XCNEW (gfc_directorylist);
     392        66623 :       if (!head)
     393        35184 :         *list = dir;
     394              :     }
     395              :   else
     396              :     {
     397              :       dir = *list;
     398        80817 :       while (dir->next)
     399              :         dir = dir->next;
     400              : 
     401        21971 :       dir->next = XCNEW (gfc_directorylist);
     402        21971 :       dir = dir->next;
     403              :     }
     404              : 
     405        57155 :   dir->next = head ? *list : NULL;
     406        57155 :   if (head)
     407        31439 :     *list = dir;
     408        88594 :   dir->use_for_modules = use_for_modules;
     409        88594 :   dir->warn = warn;
     410        88594 :   dir->path = xstrdup (p);
     411              : }
     412              : 
     413              : /* defer_warn is set to true while parsing the commandline.  */
     414              : 
     415              : void
     416        84833 : gfc_add_include_path (const char *path, bool use_for_modules, bool file_dir,
     417              :                       bool warn, bool defer_warn)
     418              : {
     419        84833 :   add_path_to_list (&include_dirs, path, use_for_modules, file_dir, warn,
     420              :                     defer_warn);
     421              : 
     422              :   /* For '#include "..."' these directories are automatically searched.  */
     423        84833 :   if (!file_dir)
     424        53392 :     gfc_cpp_add_include_path (xstrdup(path), true);
     425        84833 : }
     426              : 
     427              : 
     428              : void
     429        35184 : gfc_add_intrinsic_modules_path (const char *path)
     430              : {
     431        35184 :   add_path_to_list (&intrinsic_modules_dirs, path, true, false, false, false);
     432        35184 : }
     433              : 
     434              : 
     435              : /* Release resources allocated for options.  */
     436              : 
     437              : void
     438        31422 : gfc_release_include_path (void)
     439              : {
     440        31422 :   gfc_directorylist *p;
     441              : 
     442        84794 :   while (include_dirs != NULL)
     443              :     {
     444        53372 :       p = include_dirs;
     445        53372 :       include_dirs = include_dirs->next;
     446        53372 :       free (p->path);
     447        53372 :       free (p);
     448              :     }
     449              : 
     450        35184 :   while (intrinsic_modules_dirs != NULL)
     451              :     {
     452         3762 :       p = intrinsic_modules_dirs;
     453         3762 :       intrinsic_modules_dirs = intrinsic_modules_dirs->next;
     454         3762 :       free (p->path);
     455         3762 :       free (p);
     456              :     }
     457              : 
     458        31422 :   free (gfc_option.module_dir);
     459        31422 : }
     460              : 
     461              : 
     462              : static FILE *
     463          373 : open_included_file (const char *name, gfc_directorylist *list,
     464              :                     bool module, bool system)
     465              : {
     466          373 :   char *fullname;
     467          373 :   gfc_directorylist *p;
     468          373 :   FILE *f;
     469              : 
     470          637 :   for (p = list; p; p = p->next)
     471              :     {
     472          635 :       if (module && !p->use_for_modules)
     473            0 :         continue;
     474              : 
     475          635 :       fullname = (char *) alloca(strlen (p->path) + strlen (name) + 2);
     476          635 :       strcpy (fullname, p->path);
     477          635 :       strcat (fullname, "/");
     478          635 :       strcat (fullname, name);
     479              : 
     480          635 :       f = gfc_open_file (fullname);
     481          635 :       if (f != NULL)
     482              :         {
     483          371 :           if (gfc_cpp_makedep ())
     484            0 :             gfc_cpp_add_dep (fullname, system);
     485              : 
     486          371 :           return f;
     487              :         }
     488              :     }
     489              : 
     490              :   return NULL;
     491              : }
     492              : 
     493              : 
     494              : /* Opens file for reading, searching through the include directories
     495              :    given if necessary.  If the include_cwd argument is true, we try
     496              :    to open the file in the current directory first.  */
     497              : 
     498              : FILE *
     499        31793 : gfc_open_included_file (const char *name, bool include_cwd, bool module)
     500              : {
     501        31793 :   FILE *f = NULL;
     502              : 
     503        31793 :   if (IS_ABSOLUTE_PATH (name) || include_cwd)
     504              :     {
     505        31421 :       f = gfc_open_file (name);
     506        31421 :       if (f && gfc_cpp_makedep ())
     507            0 :         gfc_cpp_add_dep (name, false);
     508              :     }
     509              : 
     510        31421 :   if (!f)
     511          373 :     f = open_included_file (name, include_dirs, module, false);
     512              : 
     513        31793 :   return f;
     514              : }
     515              : 
     516              : 
     517              : /* Test to see if we're at the end of the main source file.  */
     518              : 
     519              : bool
     520   1209723240 : gfc_at_end (void)
     521              : {
     522   1209723240 :   return end_flag;
     523              : }
     524              : 
     525              : 
     526              : /* Test to see if we're at the end of the current file.  */
     527              : 
     528              : bool
     529     31851491 : gfc_at_eof (void)
     530              : {
     531     31851491 :   if (gfc_at_end ())
     532              :     return 1;
     533              : 
     534     31575479 :   if (line_head == NULL)
     535              :     return 1;                   /* Null file */
     536              : 
     537     31575479 :   if (gfc_current_locus.u.lb == NULL)
     538            0 :     return 1;
     539              : 
     540              :   return 0;
     541              : }
     542              : 
     543              : 
     544              : /* Test to see if we're at the beginning of a new line.  */
     545              : 
     546              : bool
     547     15053361 : gfc_at_bol (void)
     548              : {
     549     15053361 :   if (gfc_at_eof ())
     550              :     return 1;
     551              : 
     552     14931481 :   return (gfc_current_locus.nextc == gfc_current_locus.u.lb->line);
     553              : }
     554              : 
     555              : 
     556              : /* Test to see if we're at the end of a line.  */
     557              : 
     558              : bool
     559      4833181 : gfc_at_eol (void)
     560              : {
     561      4833181 :   if (gfc_at_eof ())
     562              :     return 1;
     563              : 
     564      4833177 :   return (*gfc_current_locus.nextc == '\0');
     565              : }
     566              : 
     567              : static void
     568        67836 : add_file_change (const char *filename, int line)
     569              : {
     570        67836 :   if (file_changes_count == file_changes_allocated)
     571              :     {
     572        31426 :       if (file_changes_allocated)
     573            1 :         file_changes_allocated *= 2;
     574              :       else
     575        31425 :         file_changes_allocated = 16;
     576        31426 :       file_changes = XRESIZEVEC (struct gfc_file_change, file_changes,
     577              :                                  file_changes_allocated);
     578              :     }
     579        67836 :   file_changes[file_changes_count].filename = filename;
     580        67836 :   file_changes[file_changes_count].lb = NULL;
     581        67836 :   file_changes[file_changes_count++].line = line;
     582        67836 : }
     583              : 
     584              : static void
     585      6755997 : report_file_change (gfc_linebuf *lb)
     586              : {
     587      6755997 :   size_t c = file_changes_cur;
     588      6755997 :   while (c < file_changes_count
     589      6823827 :          && file_changes[c].lb == lb)
     590              :     {
     591        67830 :       if (file_changes[c].filename)
     592        33915 :         (*debug_hooks->start_source_file) (file_changes[c].line,
     593              :                                            file_changes[c].filename);
     594              :       else
     595        33915 :         (*debug_hooks->end_source_file) (file_changes[c].line);
     596        67830 :       ++c;
     597              :     }
     598      6755997 :   file_changes_cur = c;
     599      6755997 : }
     600              : 
     601              : void
     602        31424 : gfc_start_source_files (void)
     603              : {
     604              :   /* If the debugger wants the name of the main source file,
     605              :      we give it.  */
     606        31424 :   if (debug_hooks->start_end_main_source_file)
     607         5131 :     (*debug_hooks->start_source_file) (0, gfc_source_file);
     608              : 
     609        31424 :   file_changes_cur = 0;
     610        31424 :   report_file_change (gfc_current_locus.u.lb);
     611        31424 : }
     612              : 
     613              : void
     614        31378 : gfc_end_source_files (void)
     615              : {
     616        31378 :   report_file_change (NULL);
     617              : 
     618        31378 :   if (debug_hooks->start_end_main_source_file)
     619         5131 :     (*debug_hooks->end_source_file) (0);
     620        31378 : }
     621              : 
     622              : /* Advance the current line pointer to the next line.  */
     623              : 
     624              : void
     625     11508045 : gfc_advance_line (void)
     626              : {
     627     11508045 :   if (gfc_at_end ())
     628              :     return;
     629              : 
     630     11508035 :   if (gfc_current_locus.u.lb == NULL)
     631              :     {
     632            0 :       end_flag = 1;
     633            0 :       return;
     634              :     }
     635              : 
     636     11508035 :   if (gfc_current_locus.u.lb->next
     637     11353958 :       && !gfc_current_locus.u.lb->next->dbg_emitted)
     638              :     {
     639      6693195 :       report_file_change (gfc_current_locus.u.lb->next);
     640      6693195 :       gfc_current_locus.u.lb->next->dbg_emitted = true;
     641              :     }
     642              : 
     643     11508035 :   gfc_current_locus.u.lb = gfc_current_locus.u.lb->next;
     644              : 
     645     11508035 :   if (gfc_current_locus.u.lb != NULL)
     646     11353958 :     gfc_current_locus.nextc = gfc_current_locus.u.lb->line;
     647              :   else
     648              :     {
     649       154077 :       gfc_current_locus.nextc = NULL;
     650       154077 :       end_flag = 1;
     651              :     }
     652              : }
     653              : 
     654              : 
     655              : /* Get the next character from the input, advancing gfc_current_file's
     656              :    locus.  When we hit the end of the line or the end of the file, we
     657              :    start returning a '\n' in order to complete the current statement.
     658              :    No Fortran line conventions are implemented here.
     659              : 
     660              :    Requiring explicit advances to the next line prevents the parse
     661              :    pointer from being on the wrong line if the current statement ends
     662              :    prematurely.  */
     663              : 
     664              : static gfc_char_t
     665   1393564312 : next_char (void)
     666              : {
     667   1393564312 :   gfc_char_t c;
     668              : 
     669   1393564312 :   if (gfc_current_locus.nextc == NULL)
     670              :     return '\n';
     671              : 
     672   1393441690 :   c = *gfc_current_locus.nextc++;
     673   1393441690 :   if (c == '\0')
     674              :     {
     675     42994411 :       gfc_current_locus.nextc--; /* Remain on this line.  */
     676     42994411 :       c = '\n';
     677              :     }
     678              : 
     679              :   return c;
     680              : }
     681              : 
     682              : 
     683              : /* Skip a comment.  When we come here the parse pointer is positioned
     684              :    immediately after the comment character.  If we ever implement
     685              :    compiler directives within comments, here is where we parse the
     686              :    directive.  */
     687              : 
     688              : static void
     689      1388176 : skip_comment_line (void)
     690              : {
     691     81866678 :   gfc_char_t c;
     692              : 
     693     81866678 :   do
     694              :     {
     695     81866678 :       c = next_char ();
     696              :     }
     697     81866678 :   while (c != '\n');
     698              : 
     699      1388176 :   gfc_advance_line ();
     700      1388176 : }
     701              : 
     702              : 
     703              : bool
     704      4801766 : gfc_define_undef_line (void)
     705              : {
     706      4801766 :   char *tmp;
     707              : 
     708              :   /* All lines beginning with '#' are either #define or #undef.  */
     709      4801766 :   if (debug_info_level != DINFO_LEVEL_VERBOSE || gfc_peek_ascii_char () != '#')
     710      4801758 :     return 0;
     711              : 
     712            8 :   if (wide_strncmp (gfc_current_locus.nextc, "#define ", 8) == 0)
     713              :     {
     714            5 :       tmp = gfc_widechar_to_char (&gfc_current_locus.nextc[8], -1);
     715            5 :       (*debug_hooks->define) (gfc_linebuf_linenum (gfc_current_locus.u.lb),
     716              :                               tmp);
     717            5 :       free (tmp);
     718              :     }
     719              : 
     720            8 :   if (wide_strncmp (gfc_current_locus.nextc, "#undef ", 7) == 0)
     721              :     {
     722            3 :       tmp = gfc_widechar_to_char (&gfc_current_locus.nextc[7], -1);
     723            3 :       (*debug_hooks->undef) (gfc_linebuf_linenum (gfc_current_locus.u.lb),
     724              :                              tmp);
     725            3 :       free (tmp);
     726              :     }
     727              : 
     728              :   /* Skip the rest of the line.  */
     729            8 :   skip_comment_line ();
     730              : 
     731            8 :   return 1;
     732              : }
     733              : 
     734              : 
     735              : /* Return true if GCC$ was matched.  */
     736              : static bool
     737      5109584 : skip_gcc_attribute (locus start)
     738              : {
     739      5109584 :   bool r = false;
     740      5109584 :   char c;
     741      5109584 :   locus old_loc = gfc_current_locus;
     742              : 
     743      5109584 :   if ((c = next_char ()) == 'g' || c == 'G')
     744      3636619 :     if ((c = next_char ()) == 'c' || c == 'C')
     745      3634559 :       if ((c = next_char ()) == 'c' || c == 'C')
     746      3634559 :         if ((c = next_char ()) == '$')
     747      3634559 :           r = true;
     748              : 
     749      3634559 :   if (r == false)
     750      1475025 :     gfc_current_locus = old_loc;
     751              :   else
     752              :    {
     753      3634559 :       gcc_attribute_flag = 1;
     754      3634559 :       gcc_attribute_locus = old_loc;
     755      3634559 :       gfc_current_locus = start;
     756              :    }
     757              : 
     758      5109584 :   return r;
     759              : }
     760              : 
     761              : /* Return true if CC was matched.  */
     762              : static bool
     763        20320 : skip_free_oacc_sentinel (locus start, locus old_loc)
     764              : {
     765        20320 :   bool r = false;
     766        20320 :   char c;
     767              : 
     768        20320 :   if ((c = next_char ()) == 'c' || c == 'C')
     769        20320 :     if ((c = next_char ()) == 'c' || c == 'C')
     770        20320 :       r = true;
     771              : 
     772        20320 :   if (r)
     773              :    {
     774        20332 :       if ((c = next_char ()) == ' ' || c == '\t'
     775        20332 :           || continue_flag)
     776              :         {
     777        20319 :           if (!continue_flag && (c == ' ' || c == '\t'))
     778        19840 :             openmp_flag = 0;
     779        40825 :           while (gfc_is_whitespace (c))
     780        20506 :             c = next_char ();
     781        20319 :           if (c != '\n' && c != '!')
     782              :             {
     783        20318 :               openacc_flag = 1;
     784        20318 :               openacc_locus = old_loc;
     785        20318 :               gfc_current_locus = start;
     786              :             }
     787              :           else
     788              :             r = false;
     789              :         }
     790              :       else
     791              :         {
     792            1 :           gfc_warning_now (0, "!$ACC at %C starts a commented "
     793              :                            "line as it neither is followed "
     794              :                            "by a space nor is a "
     795              :                            "continuation line");
     796            1 :           r = false;
     797              :         }
     798              :    }
     799              : 
     800        20320 :   return r;
     801              : }
     802              : 
     803              : /* Return true if MP was matched.  */
     804              : static bool
     805        39063 : skip_free_omp_sentinel (locus start, locus old_loc)
     806              : {
     807        39063 :   bool r = false;
     808        39063 :   char c;
     809              : 
     810        39063 :   if ((c = next_char ()) == 'm' || c == 'M')
     811        39062 :     if ((c = next_char ()) == 'p' || c == 'P')
     812        39062 :       r = true;
     813              : 
     814        39062 :   if (r)
     815              :    {
     816        41150 :       if ((c = next_char ()) == ' ' || c == '\t'
     817        41149 :           || continue_flag)
     818              :         {
     819        39058 :           if (!continue_flag && (c == ' ' || c == '\t'))
     820        32605 :             openacc_flag = 0;
     821        78500 :           while (gfc_is_whitespace (c))
     822        39442 :             c = next_char ();
     823        39058 :           if (c != '\n' && c != '!')
     824              :             {
     825        39058 :               openmp_flag = 1;
     826        39058 :               openmp_locus = old_loc;
     827        39058 :               gfc_current_locus = start;
     828              :             }
     829              :           else
     830              :             r = false;
     831              :         }
     832              :       else
     833              :         {
     834            4 :           gfc_warning_now (0, "!$OMP at %C starts a commented "
     835              :                            "line as it neither is followed "
     836              :                            "by a space nor is a "
     837              :                            "continuation line");
     838            4 :           r = false;
     839              :         }
     840              :    }
     841              : 
     842        39063 :   return r;
     843              : }
     844              : 
     845              : /* Comment lines are null lines, lines containing only blanks or lines
     846              :    on which the first nonblank line is a '!'.
     847              :    Return true if !$ openmp or openacc conditional compilation sentinel was
     848              :    seen.  */
     849              : 
     850              : static bool
     851      4816313 : skip_free_comments (void)
     852              : {
     853      6678514 :   locus start;
     854      6678514 :   gfc_char_t c;
     855      6678514 :   int at_bol;
     856              : 
     857      6678514 :   for (;;)
     858              :     {
     859      6678514 :       at_bol = gfc_at_bol ();
     860      6678514 :       start = gfc_current_locus;
     861      6678514 :       if (gfc_at_eof ())
     862              :         break;
     863              : 
     864     14338216 :       do
     865     14338216 :         c = next_char ();
     866     14338216 :       while (gfc_is_whitespace (c));
     867              : 
     868      6648855 :       if (c == '\n')
     869              :         {
     870      1152810 :           gfc_advance_line ();
     871      1152810 :           continue;
     872              :         }
     873              : 
     874      5496045 :       if (c == '!')
     875              :         {
     876              :           /* Keep the !GCC$ line.  */
     877      3972072 :           if (at_bol && skip_gcc_attribute (start))
     878              :             return false;
     879              : 
     880              :           /* If -fopenmp/-fopenacc, we need to handle here 2 things:
     881              :              1) don't treat !$omp/!$acc as comments, but directives
     882              :              2) handle OpenMP conditional compilation, where
     883              :                 !$ should be treated as 2 spaces (for initial lines
     884              :                 only if followed by space).  */
     885       769294 :           if (at_bol)
     886              :           {
     887       769223 :             if ((flag_openmp || flag_openmp_simd)
     888       107448 :                 && flag_openacc)
     889              :               {
     890          631 :                 locus old_loc = gfc_current_locus;
     891          631 :                 if (next_char () == '$')
     892              :                   {
     893          423 :                     c = next_char ();
     894          423 :                     if (c == 'o' || c == 'O')
     895              :                       {
     896          111 :                         if (skip_free_omp_sentinel (start, old_loc))
     897          419 :                           return false;
     898            0 :                         gfc_current_locus = old_loc;
     899            0 :                         next_char ();
     900            0 :                         c = next_char ();
     901              :                       }
     902          312 :                     else if (c == 'a' || c == 'A')
     903              :                       {
     904          192 :                         if (skip_free_oacc_sentinel (start, old_loc))
     905              :                           return false;
     906            0 :                         gfc_current_locus = old_loc;
     907            0 :                         next_char ();
     908            0 :                         c = next_char ();
     909              :                       }
     910          120 :                     if (continue_flag || c == ' ' || c == '\t')
     911              :                       {
     912          116 :                         gfc_current_locus = old_loc;
     913          116 :                         next_char ();
     914          116 :                         openmp_flag = openacc_flag = 0;
     915          116 :                         return true;
     916              :                       }
     917              :                   }
     918          212 :                 gfc_current_locus = old_loc;
     919          212 :               }
     920       768592 :             else if ((flag_openmp || flag_openmp_simd)
     921       106817 :                      && !flag_openacc)
     922              :               {
     923       106817 :                 locus old_loc = gfc_current_locus;
     924       106817 :                 if (next_char () == '$')
     925              :                   {
     926        39413 :                     c = next_char ();
     927        39413 :                     if (c == 'o' || c == 'O')
     928              :                       {
     929        38952 :                         if (skip_free_omp_sentinel (start, old_loc))
     930        39358 :                           return false;
     931            5 :                         gfc_current_locus = old_loc;
     932            5 :                         next_char ();
     933            5 :                         c = next_char ();
     934              :                       }
     935          466 :                     if (continue_flag || c == ' ' || c == '\t')
     936              :                       {
     937          411 :                         gfc_current_locus = old_loc;
     938          411 :                         next_char ();
     939          411 :                         openmp_flag = 0;
     940          411 :                         return true;
     941              :                       }
     942              :                   }
     943        67459 :                 gfc_current_locus = old_loc;
     944        67459 :               }
     945       661775 :             else if (flag_openacc
     946        57359 :                      && !(flag_openmp || flag_openmp_simd))
     947              :               {
     948        57359 :                 locus old_loc = gfc_current_locus;
     949        57359 :                 if (next_char () == '$')
     950              :                   {
     951        20160 :                     c = next_char ();
     952        20160 :                     if (c == 'a' || c == 'A')
     953              :                       {
     954        20128 :                         if (skip_free_oacc_sentinel (start, old_loc))
     955        20126 :                           return false;
     956            2 :                         gfc_current_locus = old_loc;
     957            2 :                         next_char();
     958            2 :                         c = next_char();
     959              :                       }
     960              :                   }
     961        37233 :                 gfc_current_locus = old_loc;
     962              :               }
     963              :           }
     964       709391 :           skip_comment_line ();
     965       709391 :           continue;
     966       709391 :         }
     967              : 
     968              :       break;
     969              :     }
     970              : 
     971      1553632 :   if (openmp_flag && at_bol)
     972        22528 :     openmp_flag = 0;
     973              : 
     974      1553632 :   if (openacc_flag && at_bol)
     975        11965 :     openacc_flag = 0;
     976              : 
     977      1553632 :   gcc_attribute_flag = 0;
     978      1553632 :   gfc_current_locus = start;
     979      1553632 :   return false;
     980              : }
     981              : 
     982              : /* Return true if MP was matched in fixed form.  */
     983              : static bool
     984         9918 : skip_fixed_omp_sentinel (locus *start)
     985              : {
     986         9918 :   gfc_char_t c;
     987         9918 :   if ((c = next_char ()) != 'm' && c != 'M')
     988              :     return false;
     989         9918 :   if ((c = next_char ()) == 'p' || c == 'P')
     990              :     {
     991         9894 :       c = next_char ();
     992         9894 :       if (c != '\n'
     993         9894 :           && (continue_flag
     994          277 :               || c == ' ' || c == '\t' || c == '0'))
     995              :         {
     996         9893 :           if (c == ' ' || c == '\t' || c == '0')
     997         9822 :             openacc_flag = 0;
     998        10106 :           do
     999        10106 :             c = next_char ();
    1000        10106 :           while (gfc_is_whitespace (c));
    1001         9893 :           if (c != '\n' && c != '!')
    1002              :             {
    1003              :               /* Canonicalize to *$omp.  */
    1004         9893 :               *start->nextc = '*';
    1005         9893 :               openmp_flag = 1;
    1006         9893 :               gfc_current_locus = *start;
    1007         9893 :               return true;
    1008              :             }
    1009              :         }
    1010              :     }
    1011           24 :   else if (UNLIKELY (c == 'x' || c == 'X'))
    1012           24 :     gfc_warning_now (OPT_Wsurprising,
    1013              :                      "Ignoring %<!$omx%> vendor-extension sentinel at %C");
    1014              :   return false;
    1015              : }
    1016              : 
    1017              : /* Return true if CC was matched in fixed form.  */
    1018              : static bool
    1019        41315 : skip_fixed_oacc_sentinel (locus *start)
    1020              : {
    1021        41315 :   gfc_char_t c;
    1022        69156 :   if (((c = next_char ()) == 'c' || c == 'C')
    1023        69142 :       && ((c = next_char ()) == 'c' || c == 'C'))
    1024              :     {
    1025        41301 :       c = next_char ();
    1026        41301 :       if (c != '\n'
    1027        41301 :           && (continue_flag
    1028         1052 :               || c == ' ' || c == '\t' || c == '0'))
    1029              :         {
    1030        41298 :           if (c == ' ' || c == '\t' || c == '0')
    1031        41169 :             openmp_flag = 0;
    1032        41427 :           do
    1033        41427 :             c = next_char ();
    1034        41427 :           while (gfc_is_whitespace (c));
    1035        41298 :           if (c != '\n' && c != '!')
    1036              :             {
    1037              :               /* Canonicalize to *$acc.  */
    1038        41298 :               *start->nextc = '*';
    1039        41298 :               openacc_flag = 1;
    1040        41298 :               gfc_current_locus = *start;
    1041        41298 :               return true;
    1042              :             }
    1043              :         }
    1044              :     }
    1045              :   return false;
    1046              : }
    1047              : 
    1048              : /* Skip comment lines in fixed source mode.  We have the same rules as
    1049              :    in skip_free_comment(), except that we can have a 'c', 'C' or '*'
    1050              :    in column 1, and a '!' cannot be in column 6.  Also, we deal with
    1051              :    lines with 'd' or 'D' in column 1, if the user requested this.  */
    1052              : 
    1053              : static void
    1054      3573041 : skip_fixed_comments (void)
    1055              : {
    1056      3573041 :   locus start;
    1057      3573041 :   int col;
    1058      3573041 :   gfc_char_t c;
    1059              : 
    1060      3573041 :   if (! gfc_at_bol ())
    1061              :     {
    1062           48 :       start = gfc_current_locus;
    1063           48 :       if (! gfc_at_eof ())
    1064              :         {
    1065          136 :           do
    1066          136 :             c = next_char ();
    1067          136 :           while (gfc_is_whitespace (c));
    1068              : 
    1069           48 :           if (c == '\n')
    1070            2 :             gfc_advance_line ();
    1071           46 :           else if (c == '!')
    1072            1 :             skip_comment_line ();
    1073              :         }
    1074              : 
    1075           48 :       if (! gfc_at_bol ())
    1076              :         {
    1077           45 :           gfc_current_locus = start;
    1078       483017 :           return;
    1079              :         }
    1080              :     }
    1081              : 
    1082      4899058 :   for (;;)
    1083              :     {
    1084      4899058 :       start = gfc_current_locus;
    1085      4899058 :       if (gfc_at_eof ())
    1086              :         break;
    1087              : 
    1088      4774653 :       c = next_char ();
    1089      4774653 :       if (c == '\n')
    1090              :         {
    1091         4779 :           gfc_advance_line ();
    1092         4779 :           continue;
    1093              :         }
    1094              : 
    1095              :       if (c == '!' || c == 'c' || c == 'C' || c == '*')
    1096              :         {
    1097      1137583 :           if (skip_gcc_attribute (start))
    1098              :             {
    1099              :               /* Canonicalize to *$omp.  */
    1100       431781 :               *start.nextc = '*';
    1101       431781 :               return;
    1102              :             }
    1103              : 
    1104       705802 :           if (gfc_current_locus.u.lb != NULL
    1105       705802 :               && continue_line < gfc_linebuf_linenum (gfc_current_locus.u.lb))
    1106       542956 :             continue_line = gfc_linebuf_linenum (gfc_current_locus.u.lb);
    1107              : 
    1108              :           /* If -fopenmp/-fopenacc, we need to handle here 2 things:
    1109              :              1) don't treat !$omp/!$acc|c$omp/c$acc|*$omp / *$acc as comments,
    1110              :                 but directives
    1111              :              2) handle OpenMP conditional compilation, where
    1112              :                 !$|c$|*$ should be treated as 2 spaces if the characters
    1113              :                 in columns 3 to 6 are valid fixed form label columns
    1114              :                 characters.  */
    1115       705802 :           if ((flag_openmp || flag_openmp_simd) && !flag_openacc)
    1116              :             {
    1117        68517 :               if (next_char () == '$')
    1118              :                 {
    1119         9612 :                   c = next_char ();
    1120         9612 :                   if (c == 'o' || c == 'O')
    1121              :                     {
    1122         9480 :                       if (skip_fixed_omp_sentinel (&start))
    1123              :                         return;
    1124              :                     }
    1125              :                   else
    1126          132 :                     goto check_for_digits;
    1127              :                 }
    1128        58929 :               gfc_current_locus = start;
    1129              :             }
    1130       637285 :           else if (flag_openacc && !(flag_openmp || flag_openmp_simd))
    1131              :             {
    1132       153540 :               if (next_char () == '$')
    1133              :                 {
    1134        41133 :                   c = next_char ();
    1135        41133 :                   if (c == 'a' || c == 'A')
    1136              :                     {
    1137        41017 :                       if (skip_fixed_oacc_sentinel (&start))
    1138              :                         return;
    1139              :                     }
    1140              :                 }
    1141       112525 :               gfc_current_locus = start;
    1142              :             }
    1143       483745 :           else if (flag_openacc || flag_openmp || flag_openmp_simd)
    1144              :             {
    1145         2707 :               if (next_char () == '$')
    1146              :                 {
    1147         1298 :                   c = next_char ();
    1148         1298 :                   if (c == 'a' || c == 'A')
    1149              :                     {
    1150          298 :                       if (skip_fixed_oacc_sentinel (&start))
    1151              :                         return;
    1152              :                     }
    1153         1000 :                   else if (c == 'o' || c == 'O')
    1154              :                     {
    1155          438 :                       if (skip_fixed_omp_sentinel (&start))
    1156              :                         return;
    1157              :                     }
    1158              :                   else
    1159          562 :                     goto check_for_digits;
    1160              :                 }
    1161         1425 :               gfc_current_locus = start;
    1162              :             }
    1163              : 
    1164       653917 :           skip_comment_line ();
    1165       653917 :           continue;
    1166              : 
    1167              : check_for_digits:
    1168              :           {
    1169              :             /* Required for OpenMP's conditional compilation sentinel. */
    1170              :             int digit_seen = 0;
    1171              : 
    1172         1382 :             for (col = 3; col < 6; col++, c = next_char ())
    1173         1300 :               if (c == ' ')
    1174          578 :                 continue;
    1175          722 :               else if (c == '\t')
    1176              :                 {
    1177              :                   col = 6;
    1178              :                   break;
    1179              :                 }
    1180          722 :               else if (c < '0' || c > '9')
    1181              :                 break;
    1182              :               else
    1183              :                 digit_seen = 1;
    1184              : 
    1185          694 :             if (col == 6 && c != '\n'
    1186           82 :                 && ((continue_flag && !digit_seen)
    1187           47 :                     || c == ' ' || c == '\t' || c == '0'))
    1188              :               {
    1189           45 :                 gfc_current_locus = start;
    1190           45 :                 start.nextc[0] = ' ';
    1191           45 :                 start.nextc[1] = ' ';
    1192           45 :                 continue;
    1193              :               }
    1194              :             }
    1195          649 :           skip_comment_line ();
    1196          649 :           continue;
    1197       654566 :         }
    1198              : 
    1199      3632291 :       if (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))
    1200              :         {
    1201           16 :           if (gfc_option.flag_d_lines == 0)
    1202              :             {
    1203            8 :               skip_comment_line ();
    1204            8 :               continue;
    1205              :             }
    1206              :           else
    1207            8 :             *start.nextc = c = ' ';
    1208              :         }
    1209              : 
    1210              :       col = 1;
    1211              : 
    1212     72259243 :       while (gfc_is_whitespace (c))
    1213              :         {
    1214     68626960 :           c = next_char ();
    1215     68626960 :           col++;
    1216              :         }
    1217              : 
    1218      3632283 :       if (c == '\n')
    1219              :         {
    1220       656297 :           gfc_advance_line ();
    1221       656297 :           continue;
    1222              :         }
    1223              : 
    1224      2975986 :       if (col != 6 && c == '!')
    1225              :         {
    1226        10367 :           if (gfc_current_locus.u.lb != NULL
    1227        10367 :               && continue_line < gfc_linebuf_linenum (gfc_current_locus.u.lb))
    1228         5489 :             continue_line = gfc_linebuf_linenum (gfc_current_locus.u.lb);
    1229        10367 :           skip_comment_line ();
    1230        10367 :           continue;
    1231              :         }
    1232              : 
    1233              :       break;
    1234              :     }
    1235              : 
    1236      3090024 :   openmp_flag = 0;
    1237      3090024 :   openacc_flag = 0;
    1238      3090024 :   gcc_attribute_flag = 0;
    1239      3090024 :   gfc_current_locus = start;
    1240              : }
    1241              : 
    1242              : 
    1243              : /* Skips the current line if it is a comment.  */
    1244              : 
    1245              : void
    1246      4833284 : gfc_skip_comments (void)
    1247              : {
    1248      4833284 :   if (gfc_current_form == FORM_FREE)
    1249      4554521 :     skip_free_comments ();
    1250              :   else
    1251       278763 :     skip_fixed_comments ();
    1252      4833284 : }
    1253              : 
    1254              : 
    1255              : /* Get the next character from the input, taking continuation lines
    1256              :    and end-of-line comments into account.  This implies that comment
    1257              :    lines between continued lines must be eaten here.  For higher-level
    1258              :    subroutines, this flattens continued lines into a single logical
    1259              :    line.  The in_string flag denotes whether we're inside a character
    1260              :    context or not.  */
    1261              : 
    1262              : gfc_char_t
    1263   1161464974 : gfc_next_char_literal (gfc_instring in_string)
    1264              : {
    1265   1161464974 :   static locus omp_acc_err_loc = {};
    1266   1161464974 :   locus old_loc;
    1267   1161464974 :   int i, prev_openmp_flag, prev_openacc_flag;
    1268   1161464974 :   gfc_char_t c;
    1269              : 
    1270   1161464974 :   continue_flag = 0;
    1271   1161464974 :   prev_openacc_flag = prev_openmp_flag = 0;
    1272              : 
    1273   1161530523 : restart:
    1274   1161530523 :   c = next_char ();
    1275   1161530523 :   if (gfc_at_end ())
    1276              :     {
    1277          170 :       continue_count = 0;
    1278          170 :       return c;
    1279              :     }
    1280              : 
    1281   1161530353 :   if (gfc_current_form == FORM_FREE)
    1282              :     {
    1283   1040861370 :       bool openmp_cond_flag;
    1284              : 
    1285   1040861370 :       if (!in_string && c == '!')
    1286              :         {
    1287     10400450 :           if (gcc_attribute_flag
    1288      9609282 :               && memcmp (&gfc_current_locus, &gcc_attribute_locus,
    1289              :                  sizeof (gfc_current_locus)) == 0)
    1290      9608766 :             goto done;
    1291              : 
    1292       791684 :           if (openmp_flag
    1293       111455 :               && memcmp (&gfc_current_locus, &openmp_locus,
    1294              :                  sizeof (gfc_current_locus)) == 0)
    1295        97815 :             goto done;
    1296              : 
    1297       693869 :           if (openacc_flag
    1298        74210 :               && memcmp (&gfc_current_locus, &openacc_locus,
    1299              :                  sizeof (gfc_current_locus)) == 0)
    1300        59517 :             goto done;
    1301              : 
    1302              :           /* This line can't be continued */
    1303     22513196 :           do
    1304              :             {
    1305     22513196 :               c = next_char ();
    1306              :             }
    1307     22513196 :           while (c != '\n');
    1308              : 
    1309              :           /* Avoid truncation warnings for comment ending lines.  */
    1310       634352 :           gfc_current_locus.u.lb->truncated = 0;
    1311              : 
    1312       634352 :           goto done;
    1313              :         }
    1314              : 
    1315              :       /* Check to see if the continuation line was truncated.  */
    1316   1030460920 :       if (warn_line_truncation && gfc_current_locus.u.lb != NULL
    1317   1030369616 :           && gfc_current_locus.u.lb->truncated)
    1318              :         {
    1319           14 :           int maxlen = flag_free_line_length;
    1320           14 :           gfc_char_t *current_nextc = gfc_current_locus.nextc;
    1321              : 
    1322           14 :           gfc_current_locus.u.lb->truncated = 0;
    1323           14 :           gfc_current_locus.nextc =  gfc_current_locus.u.lb->line + maxlen;
    1324           14 :           gfc_warning_now (OPT_Wline_truncation,
    1325              :                            "Line truncated at %L", &gfc_current_locus);
    1326           14 :           gfc_current_locus.nextc = current_nextc;
    1327              :         }
    1328              : 
    1329   1030460920 :       if (c != '&')
    1330   1030194808 :         goto done;
    1331              : 
    1332              :       /* If the next nonblank character is a ! or \n, we've got a
    1333              :          continuation line.  */
    1334       266112 :       old_loc = gfc_current_locus;
    1335              : 
    1336       266112 :       c = next_char ();
    1337       553868 :       while (gfc_is_whitespace (c))
    1338        21644 :         c = next_char ();
    1339              : 
    1340              :       /* Character constants to be continued cannot have commentary
    1341              :          after the '&'. However, there are cases where we may think we
    1342              :          are still in a string and we are looking for a possible
    1343              :          doubled quote and we end up here. See PR64506.  */
    1344              : 
    1345       266112 :       if (in_string && c != '\n')
    1346              :         {
    1347         4102 :           gfc_current_locus = old_loc;
    1348         4102 :           c = '&';
    1349         4102 :           goto done;
    1350              :         }
    1351              : 
    1352       262010 :       if (c != '!' && c != '\n')
    1353              :         {
    1354          195 :           gfc_current_locus = old_loc;
    1355          195 :           c = '&';
    1356          195 :           goto done;
    1357              :         }
    1358              : 
    1359       261815 :       if (flag_openmp)
    1360        27009 :         prev_openmp_flag = openmp_flag;
    1361       261815 :       if (flag_openacc)
    1362         4870 :         prev_openacc_flag = openacc_flag;
    1363              : 
    1364              :       /* This can happen if the input file changed or via cpp's #line
    1365              :          without getting reset (e.g. via input_stmt). It also happens
    1366              :          when pre-including files via -fpre-include=.  */
    1367       261815 :       if (continue_count == 0
    1368       118648 :           && gfc_current_locus.u.lb
    1369       380463 :           && continue_line > gfc_linebuf_linenum (gfc_current_locus.u.lb) + 1)
    1370         3929 :         continue_line = gfc_linebuf_linenum (gfc_current_locus.u.lb) + 1;
    1371              : 
    1372       261815 :       continue_flag = 1;
    1373       261815 :       if (c == '!')
    1374        13835 :         skip_comment_line ();
    1375              :       else
    1376       247980 :         gfc_advance_line ();
    1377              : 
    1378       261815 :       if (gfc_at_eof ())
    1379           23 :         goto not_continuation;
    1380              : 
    1381              :       /* We've got a continuation line.  If we are on the very next line after
    1382              :          the last continuation, increment the continuation line count and
    1383              :          check whether the limit has been exceeded.  */
    1384       261792 :       if (gfc_linebuf_linenum (gfc_current_locus.u.lb) == continue_line + 1)
    1385              :         {
    1386        20788 :           if (++continue_count == gfc_option.max_continue_free)
    1387              :             {
    1388            4 :               if (gfc_notification_std (GFC_STD_GNU) || pedantic)
    1389            4 :                 gfc_warning (0, "Limit of %d continuations exceeded in "
    1390              :                              "statement at %C", gfc_option.max_continue_free);
    1391              :             }
    1392              :         }
    1393              : 
    1394              :       /* Now find where it continues. First eat any comment lines.  */
    1395       261792 :       openmp_cond_flag = skip_free_comments ();
    1396              : 
    1397       261792 :       if (gfc_current_locus.u.lb != NULL
    1398       261792 :           && continue_line < gfc_linebuf_linenum (gfc_current_locus.u.lb))
    1399        36676 :         continue_line = gfc_linebuf_linenum (gfc_current_locus.u.lb);
    1400              : 
    1401       261792 :       if (flag_openmp)
    1402        27004 :         if (prev_openmp_flag != openmp_flag && !openacc_flag)
    1403              :           {
    1404          278 :             gfc_current_locus = old_loc;
    1405          278 :             openmp_flag = prev_openmp_flag;
    1406          278 :             c = '&';
    1407          278 :             goto done;
    1408              :           }
    1409              : 
    1410       261514 :       if (flag_openacc)
    1411         4870 :         if (prev_openacc_flag != openacc_flag && !openmp_flag)
    1412              :           {
    1413            5 :             gfc_current_locus = old_loc;
    1414            5 :             openacc_flag = prev_openacc_flag;
    1415            5 :             c = '&';
    1416            5 :             goto done;
    1417              :           }
    1418              : 
    1419              :       /* Now that we have a non-comment line, probe ahead for the
    1420              :          first non-whitespace character.  If it is another '&', then
    1421              :          reading starts at the next character, otherwise we must back
    1422              :          up to where the whitespace started and resume from there.  */
    1423              : 
    1424       261509 :       old_loc = gfc_current_locus;
    1425              : 
    1426       261509 :       c = next_char ();
    1427      3941605 :       while (gfc_is_whitespace (c))
    1428      3418587 :         c = next_char ();
    1429              : 
    1430       261509 :       if (openmp_flag && !openacc_flag)
    1431              :         {
    1432        37674 :           for (i = 0; i < 5; i++, c = next_char ())
    1433              :             {
    1434        31395 :               gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$omp"[i]);
    1435        31395 :               if (i == 4)
    1436         6279 :                 old_loc = gfc_current_locus;
    1437              :             }
    1438        12917 :           while (gfc_is_whitespace (c))
    1439         6638 :             c = next_char ();
    1440              :         }
    1441       261509 :       if (openacc_flag && !openmp_flag)
    1442              :         {
    1443         2550 :           for (i = 0; i < 5; i++, c = next_char ())
    1444              :             {
    1445         2125 :               gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
    1446         2125 :               if (i == 4)
    1447          425 :                 old_loc = gfc_current_locus;
    1448              :             }
    1449         1034 :           while (gfc_is_whitespace (c))
    1450          609 :             c = next_char ();
    1451              :         }
    1452              : 
    1453              :       /* In case we have an OpenMP directive continued by OpenACC
    1454              :          sentinel, or vice versa, we get both openmp_flag and
    1455              :          openacc_flag on.  */
    1456              : 
    1457       261509 :       if (openacc_flag && openmp_flag)
    1458              :         {
    1459              :           int is_openmp = 0;
    1460          372 :           for (i = 0; i < 5; i++, c = next_char ())
    1461              :             {
    1462          310 :               if (gfc_wide_tolower (c) != (unsigned char) "!$acc"[i])
    1463           24 :                 is_openmp = 1;
    1464              :             }
    1465           62 :           if (omp_acc_err_loc.nextc != gfc_current_locus.nextc
    1466           59 :               || omp_acc_err_loc.u.lb != gfc_current_locus.u.lb)
    1467            5 :             gfc_error_now (is_openmp
    1468              :                            ? G_("Wrong OpenACC continuation at %C: "
    1469              :                                 "expected !$ACC, got !$OMP")
    1470              :                            : G_("Wrong OpenMP continuation at %C: "
    1471              :                                 "expected !$OMP, got !$ACC"));
    1472           62 :           omp_acc_err_loc = gfc_current_locus;
    1473           62 :           goto not_continuation;
    1474              :         }
    1475              : 
    1476       261447 :       if (c != '&')
    1477              :         {
    1478       243613 :           if (in_string && gfc_current_locus.nextc)
    1479              :             {
    1480           44 :               gfc_current_locus.nextc--;
    1481           44 :               if (warn_ampersand && in_string == INSTRING_WARN)
    1482           14 :                 gfc_warning (OPT_Wampersand,
    1483              :                              "Missing %<&%> in continued character "
    1484              :                              "constant at %C");
    1485              :             }
    1486       243568 :           else if (!in_string && (c == '\'' || c == '"'))
    1487        86611 :               goto done;
    1488              :           /* Both !$omp and !$ -fopenmp continuation lines have & on the
    1489              :              continuation line only optionally.  */
    1490       156958 :           else if (openmp_flag || openacc_flag || openmp_cond_flag)
    1491              :             {
    1492         2763 :               if (gfc_current_locus.nextc)
    1493         2763 :                   gfc_current_locus.nextc--;
    1494              :             }
    1495              :           else
    1496              :             {
    1497       154195 :               c = ' ';
    1498       154195 :               gfc_current_locus = old_loc;
    1499       154195 :               goto done;
    1500              :             }
    1501              :         }
    1502              :     }
    1503              :   else /* Fixed form.  */
    1504              :     {
    1505              :       /* Fixed form continuation.  */
    1506    120668983 :       if (in_string != INSTRING_WARN && c == '!')
    1507              :         {
    1508              :           /* Skip comment at end of line.  */
    1509      1692091 :           do
    1510              :             {
    1511      1692091 :               c = next_char ();
    1512              :             }
    1513      1692091 :           while (c != '\n');
    1514              : 
    1515              :           /* Avoid truncation warnings for comment ending lines.  */
    1516        39219 :           gfc_current_locus.u.lb->truncated = 0;
    1517              :         }
    1518              : 
    1519    120668983 :       if (c != '\n')
    1520    117374705 :         goto done;
    1521              : 
    1522              :       /* Check to see if the continuation line was truncated.  */
    1523      3294278 :       if (warn_line_truncation && gfc_current_locus.u.lb != NULL
    1524        19130 :           && gfc_current_locus.u.lb->truncated)
    1525              :         {
    1526            5 :           gfc_current_locus.u.lb->truncated = 0;
    1527            5 :           gfc_warning_now (OPT_Wline_truncation,
    1528              :                            "Line truncated at %L", &gfc_current_locus);
    1529              :         }
    1530              : 
    1531      3294278 :       if (flag_openmp)
    1532       460572 :         prev_openmp_flag = openmp_flag;
    1533      3294278 :       if (flag_openacc)
    1534      1015922 :         prev_openacc_flag = openacc_flag;
    1535              : 
    1536              :       /* This can happen if the input file changed or via cpp's #line
    1537              :          without getting reset (e.g. via input_stmt). It also happens
    1538              :          when pre-including files via -fpre-include=.  */
    1539      3294278 :       if (continue_count == 0
    1540      3264188 :           && gfc_current_locus.u.lb
    1541      6558466 :           && continue_line > gfc_linebuf_linenum (gfc_current_locus.u.lb) + 1)
    1542        89231 :         continue_line = gfc_linebuf_linenum (gfc_current_locus.u.lb) + 1;
    1543              : 
    1544      3294278 :       continue_flag = 1;
    1545      3294278 :       old_loc = gfc_current_locus;
    1546              : 
    1547      3294278 :       gfc_advance_line ();
    1548      3294278 :       skip_fixed_comments ();
    1549              : 
    1550              :       /* See if this line is a continuation line.  */
    1551      3294278 :       if (flag_openmp && openmp_flag != prev_openmp_flag && !openacc_flag)
    1552              :         {
    1553        10984 :           openmp_flag = prev_openmp_flag;
    1554        10984 :           goto not_continuation;
    1555              :         }
    1556      3283294 :       if (flag_openacc && openacc_flag != prev_openacc_flag && !openmp_flag)
    1557              :         {
    1558        42403 :           openacc_flag = prev_openacc_flag;
    1559        42403 :           goto not_continuation;
    1560              :         }
    1561              : 
    1562              :       /* In case we have an OpenMP directive continued by OpenACC
    1563              :          sentinel, or vice versa, we get both openmp_flag and
    1564              :          openacc_flag on.  */
    1565      3240891 :       if (openacc_flag && openmp_flag)
    1566              :         {
    1567              :           int is_openmp = 0;
    1568          516 :           for (i = 0; i < 5; i++)
    1569              :             {
    1570          430 :               c = next_char ();
    1571          430 :               if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
    1572           24 :                 is_openmp = 1;
    1573              :             }
    1574           86 :           if (omp_acc_err_loc.nextc != gfc_current_locus.nextc
    1575           82 :               || omp_acc_err_loc.u.lb != gfc_current_locus.u.lb)
    1576            7 :             gfc_error_now (is_openmp
    1577              :                            ? G_("Wrong OpenACC continuation at %C: "
    1578              :                                 "expected !$ACC, got !$OMP")
    1579              :                            : G_("Wrong OpenMP continuation at %C: "
    1580              :                                 "expected !$OMP, got !$ACC"));
    1581           86 :           omp_acc_err_loc = gfc_current_locus;
    1582           86 :           goto not_continuation;
    1583              :         }
    1584      3240805 :       else if (!openmp_flag && !openacc_flag)
    1585     17234618 :         for (i = 0; i < 5; i++)
    1586              :           {
    1587     14477231 :             c = next_char ();
    1588     14477231 :             if (c != ' ')
    1589       481176 :               goto not_continuation;
    1590              :           }
    1591         2242 :       else if (openmp_flag)
    1592         4686 :         for (i = 0; i < 5; i++)
    1593              :           {
    1594         3905 :             c = next_char ();
    1595         3905 :             if (gfc_wide_tolower (c) != (unsigned char) "*$omp"[i])
    1596            0 :               goto not_continuation;
    1597              :           }
    1598         1461 :       else if (openacc_flag)
    1599         8766 :         for (i = 0; i < 5; i++)
    1600              :           {
    1601         7305 :             c = next_char ();
    1602         7305 :             if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
    1603            0 :               goto not_continuation;
    1604              :           }
    1605              : 
    1606      2759629 :       c = next_char ();
    1607      2759629 :       if (c == '0' || c == ' ' || c == '\n')
    1608      2714721 :         goto not_continuation;
    1609              : 
    1610              :       /* We've got a continuation line.  If we are on the very next line after
    1611              :          the last continuation, increment the continuation line count and
    1612              :          check whether the limit has been exceeded.  */
    1613        44908 :       if (gfc_linebuf_linenum (gfc_current_locus.u.lb) == continue_line + 1)
    1614              :         {
    1615         4083 :           if (++continue_count == gfc_option.max_continue_fixed)
    1616              :             {
    1617            2 :               if (gfc_notification_std (GFC_STD_GNU) || pedantic)
    1618            2 :                 gfc_warning (0, "Limit of %d continuations exceeded in "
    1619              :                              "statement at %C",
    1620              :                              gfc_option.max_continue_fixed);
    1621              :             }
    1622              :         }
    1623              : 
    1624        44908 :       if (gfc_current_locus.u.lb != NULL
    1625        44908 :           && continue_line < gfc_linebuf_linenum (gfc_current_locus.u.lb))
    1626         6589 :         continue_line = gfc_linebuf_linenum (gfc_current_locus.u.lb);
    1627              :     }
    1628              : 
    1629              :   /* Ready to read first character of continuation line, which might
    1630              :      be another continuation line!  */
    1631        65549 :   goto restart;
    1632              : 
    1633      3249455 : not_continuation:
    1634      3249455 :   c = '\n';
    1635      3249455 :   gfc_current_locus = old_loc;
    1636      3249455 :   end_flag = 0;
    1637              : 
    1638   1161464804 : done:
    1639   1161464804 :   if (c == '\n')
    1640     39361587 :     continue_count = 0;
    1641   1161464804 :   continue_flag = 0;
    1642   1161464804 :   return c;
    1643              : }
    1644              : 
    1645              : 
    1646              : /* Get the next character of input, folded to lowercase.  In fixed
    1647              :    form mode, we also ignore spaces.  When matcher subroutines are
    1648              :    parsing character literals, they have to call
    1649              :    gfc_next_char_literal().  */
    1650              : 
    1651              : gfc_char_t
    1652    675440134 : gfc_next_char (void)
    1653              : {
    1654    703594748 :   gfc_char_t c;
    1655              : 
    1656    703594748 :   do
    1657              :     {
    1658    703594748 :       c = gfc_next_char_literal (NONSTRING);
    1659              :     }
    1660    703594748 :   while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
    1661              : 
    1662    675440134 :   return gfc_wide_tolower (c);
    1663              : }
    1664              : 
    1665              : char
    1666    626531172 : gfc_next_ascii_char (void)
    1667              : {
    1668    626531172 :   gfc_char_t c = gfc_next_char ();
    1669              : 
    1670    626531172 :   return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
    1671    626531172 :                                     : (unsigned char) UCHAR_MAX);
    1672              : }
    1673              : 
    1674              : 
    1675              : gfc_char_t
    1676     38230042 : gfc_peek_char (void)
    1677              : {
    1678     38230042 :   locus old_loc;
    1679     38230042 :   gfc_char_t c;
    1680              : 
    1681     38230042 :   old_loc = gfc_current_locus;
    1682     38230042 :   c = gfc_next_char ();
    1683     38230042 :   gfc_current_locus = old_loc;
    1684              : 
    1685     38230042 :   return c;
    1686              : }
    1687              : 
    1688              : 
    1689              : char
    1690     38217132 : gfc_peek_ascii_char (void)
    1691              : {
    1692     38217132 :   gfc_char_t c = gfc_peek_char ();
    1693              : 
    1694     38217132 :   return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
    1695     38217132 :                                     : (unsigned char) UCHAR_MAX);
    1696              : }
    1697              : 
    1698              : 
    1699              : /* Recover from an error.  We try to get past the current statement
    1700              :    and get lined up for the next.  The next statement follows a '\n'
    1701              :    or a ';'.  We also assume that we are not within a character
    1702              :    constant, and deal with finding a '\'' or '"'.  */
    1703              : 
    1704              : void
    1705         3400 : gfc_error_recovery (void)
    1706              : {
    1707         3400 :   gfc_char_t c, delim;
    1708              : 
    1709         3400 :   if (gfc_at_eof ())
    1710              :     return;
    1711              : 
    1712        94049 :   for (;;)
    1713              :     {
    1714        94049 :       c = gfc_next_char ();
    1715        94049 :       if (c == '\n' || c == ';')
    1716              :         break;
    1717              : 
    1718        90657 :       if (c != '\'' && c != '"')
    1719              :         {
    1720        90235 :           if (gfc_at_eof ())
    1721              :             break;
    1722        90235 :           continue;
    1723              :         }
    1724              :       delim = c;
    1725              : 
    1726         2987 :       for (;;)
    1727              :         {
    1728         2987 :           c = next_char ();
    1729              : 
    1730         2987 :           if (c == delim)
    1731              :             break;
    1732         2572 :           if (c == '\n')
    1733              :             return;
    1734         2565 :           if (c == '\\')
    1735              :             {
    1736            8 :               c = next_char ();
    1737            8 :               if (c == '\n')
    1738              :                 return;
    1739              :             }
    1740              :         }
    1741          415 :       if (gfc_at_eof ())
    1742              :         break;
    1743              :     }
    1744              : }
    1745              : 
    1746              : 
    1747              : /* Read ahead until the next character to be read is not whitespace.  */
    1748              : 
    1749              : void
    1750    349997765 : gfc_gobble_whitespace (void)
    1751              : {
    1752    436493496 :   static int linenum = 0;
    1753    436493496 :   locus old_loc;
    1754    436493496 :   gfc_char_t c;
    1755              : 
    1756    436493496 :   do
    1757              :     {
    1758    436493496 :       old_loc = gfc_current_locus;
    1759    436493496 :       c = gfc_next_char_literal (NONSTRING);
    1760              :       /* Issue a warning for nonconforming tabs.  We keep track of the line
    1761              :          number because the Fortran matchers will often back up and the same
    1762              :          line will be scanned multiple times.  */
    1763    436493496 :       if (warn_tabs && c == '\t')
    1764              :         {
    1765           24 :           int cur_linenum = LOCATION_LINE (gfc_current_locus.u.lb->location);
    1766           24 :           if (cur_linenum != linenum)
    1767              :             {
    1768            3 :               linenum = cur_linenum;
    1769            3 :               gfc_warning_now (OPT_Wtabs, "Nonconforming tab character at %C");
    1770              :             }
    1771              :         }
    1772              :     }
    1773    436493496 :   while (gfc_is_whitespace (c));
    1774              : 
    1775    349997765 :   if (!ISPRINT(c) && c != '\n' && last_error_char != gfc_current_locus.nextc)
    1776              :     {
    1777            2 :       char buf[20];
    1778            2 :       last_error_char = gfc_current_locus.nextc;
    1779            2 :       snprintf (buf, 20, "%2.2X", c);
    1780            2 :       gfc_error_now ("Invalid character 0x%s at %C", buf);
    1781              :     }
    1782              : 
    1783    349997765 :   gfc_current_locus = old_loc;
    1784    349997765 : }
    1785              : 
    1786              : 
    1787              : /* Load a single line into pbuf.
    1788              : 
    1789              :    If pbuf points to a NULL pointer, it is allocated.
    1790              :    We truncate lines that are too long, unless we're dealing with
    1791              :    preprocessor lines or if the option -ffixed-line-length-none is set,
    1792              :    in which case we reallocate the buffer to fit the entire line, if
    1793              :    need be.
    1794              :    In fixed mode, we expand a tab that occurs within the statement
    1795              :    label region to expand to spaces that leave the next character in
    1796              :    the source region.
    1797              : 
    1798              :    If first_char is not NULL, it's a pointer to a single char value holding
    1799              :    the first character of the line, which has already been read by the
    1800              :    caller.  This avoids the use of ungetc().
    1801              : 
    1802              :    load_line returns whether the line was truncated.
    1803              : 
    1804              :    NOTE: The error machinery isn't available at this point, so we can't
    1805              :          easily report line and column numbers consistent with other
    1806              :          parts of gfortran.  */
    1807              : 
    1808              : static bool
    1809      6797565 : load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
    1810              : {
    1811      6797565 :   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
    1812      6797565 :   int quoted = ' ', comment_ix = -1;
    1813      6797565 :   bool seen_comment = false;
    1814      6797565 :   bool first_comment = true;
    1815      6797565 :   bool trunc_flag = false;
    1816      6797565 :   bool seen_printable = false;
    1817      6797565 :   bool seen_ampersand = false;
    1818      6797565 :   bool found_tab = false;
    1819      6797565 :   bool warned_tabs = false;
    1820      6797565 :   gfc_char_t *buffer;
    1821              : 
    1822              :   /* Determine the maximum allowed line length.  */
    1823      6797565 :   if (gfc_current_form == FORM_FREE)
    1824      6444252 :     maxlen = flag_free_line_length;
    1825       353313 :   else if (gfc_current_form == FORM_FIXED)
    1826       353313 :     maxlen = flag_fixed_line_length;
    1827              :   else
    1828              :     maxlen = 72;
    1829              : 
    1830      6797565 :   if (*pbuf == NULL)
    1831              :     {
    1832              :       /* Allocate the line buffer, storing its length into buflen.
    1833              :          Note that if maxlen==0, indicating that arbitrary-length lines
    1834              :          are allowed, the buffer will be reallocated if this length is
    1835              :          insufficient; since 132 characters is the length of a standard
    1836              :          free-form line, we use that as a starting guess.  */
    1837        63226 :       if (maxlen > 0)
    1838              :         buflen = maxlen;
    1839              :       else
    1840          308 :         buflen = 132;
    1841              : 
    1842        63226 :       *pbuf = gfc_get_wide_string (buflen + 1);
    1843              :     }
    1844              : 
    1845      6797565 :   i = 0;
    1846      6797565 :   buffer = *pbuf;
    1847              : 
    1848      6797565 :   if (first_char)
    1849           10 :     c = *first_char;
    1850              :   else
    1851      6797555 :     c = getc (input);
    1852              : 
    1853              :   /* In order to not truncate preprocessor lines, we have to
    1854              :      remember that this is one.  */
    1855      6797565 :   preprocessor_flag = (c == '#');
    1856              : 
    1857    296510189 :   for (;;)
    1858              :     {
    1859    296510189 :       if (c == EOF)
    1860              :         break;
    1861              : 
    1862              :       if (c == '\n')
    1863              :         {
    1864              :           /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3.  */
    1865      6734221 :           if (gfc_current_form == FORM_FREE
    1866      6384557 :               && !seen_printable && seen_ampersand)
    1867              :             {
    1868            9 :               if (pedantic)
    1869            0 :                 gfc_error_now ("%<&%> not allowed by itself in line %d",
    1870              :                                current_file->line);
    1871              :               else
    1872            9 :                 gfc_warning_now (0, "%<&%> not allowed by itself in line %d",
    1873              :                                  current_file->line);
    1874              :             }
    1875              :           break;
    1876              :         }
    1877              : 
    1878              :       if (c == '\r' || c == '\0')
    1879        10955 :         goto next_char;                 /* Gobble characters.  */
    1880              : 
    1881              :       if (c == '&')
    1882              :         {
    1883        40043 :           if (seen_ampersand)
    1884              :             {
    1885              :               seen_ampersand = false;
    1886              :               seen_printable = true;
    1887              :             }
    1888              :           else
    1889        37468 :             seen_ampersand = true;
    1890              :         }
    1891              : 
    1892    289701669 :       if ((c != '&' && c != '!' && c != ' ') || (c == '!' && !seen_ampersand))
    1893    252192349 :         seen_printable = true;
    1894              : 
    1895              :       /* Is this a fixed-form comment?  */
    1896    289701669 :       if (gfc_current_form == FORM_FIXED && i == 0
    1897       334185 :           && (c == '*' || c == 'c' || c == 'C'
    1898       320074 :               || (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))))
    1899              :         {
    1900    289701669 :           seen_comment = true;
    1901    289701669 :           comment_ix = i;
    1902              :         }
    1903              : 
    1904    289701669 :       if (quoted == ' ')
    1905              :         {
    1906    267369119 :           if (c == '\'' || c == '"')
    1907    289701669 :             quoted = c;
    1908              :         }
    1909     22332550 :       else if (c == quoted)
    1910    267359516 :         quoted = ' ';
    1911              : 
    1912              :       /* Is this a free-form comment?  */
    1913    289701669 :       if (c == '!' && quoted == ' ')
    1914              :         {
    1915      4236828 :           if (seen_comment)
    1916              :             first_comment = false;
    1917              :           seen_comment = true;
    1918              :           comment_ix = i;
    1919              :         }
    1920              : 
    1921              :       /* For truncation and tab warnings, set seen_comment to false if one has
    1922              :          either an OpenMP or OpenACC directive - or a !GCC$ attribute.  If
    1923              :          OpenMP is enabled, use '!$' as conditional compilation sentinel
    1924              :          and OpenMP directive ('!$omp').  */
    1925    289696520 :       if (seen_comment && first_comment && flag_openmp && comment_ix + 1 == i
    1926       429754 :           && c == '$')
    1927              :         first_comment = seen_comment = false;
    1928    289666123 :       if (seen_comment && first_comment && comment_ix + 4 == i)
    1929              :         {
    1930      4068987 :           if (((*pbuf)[comment_ix+1] == 'g' || (*pbuf)[comment_ix+1] == 'G')
    1931      3398457 :               && ((*pbuf)[comment_ix+2] == 'c' || (*pbuf)[comment_ix+2] == 'C')
    1932      3396398 :               && ((*pbuf)[comment_ix+3] == 'c' || (*pbuf)[comment_ix+3] == 'C')
    1933      3396398 :               && c == '$')
    1934      4068987 :             first_comment = seen_comment = false;
    1935      4068987 :           if (flag_openacc
    1936       214936 :               && (*pbuf)[comment_ix+1] == '$'
    1937        20905 :               && ((*pbuf)[comment_ix+2] == 'a' || (*pbuf)[comment_ix+2] == 'A')
    1938        20849 :               && ((*pbuf)[comment_ix+3] == 'c' || (*pbuf)[comment_ix+3] == 'C')
    1939        20848 :               && (c == 'c' || c == 'C'))
    1940    289701669 :             first_comment = seen_comment = false;
    1941              :         }
    1942              : 
    1943              :       /* Vendor extension: "<tab>1" marks a continuation line.  */
    1944    289701669 :       if (found_tab)
    1945              :         {
    1946          106 :           found_tab = false;
    1947          106 :           if (c >= '1' && c <= '9')
    1948              :             {
    1949            1 :               *(buffer-1) = c;
    1950            1 :               goto next_char;
    1951              :             }
    1952              :         }
    1953              : 
    1954    289701668 :       if (gfc_current_form == FORM_FIXED && c == '\t' && i < 6)
    1955              :         {
    1956          106 :           found_tab = true;
    1957              : 
    1958          106 :           if (warn_tabs && seen_comment == 0 && !warned_tabs)
    1959              :             {
    1960            4 :               warned_tabs = true;
    1961            4 :               gfc_warning_now (OPT_Wtabs,
    1962              :                                "Nonconforming tab character in column %d "
    1963              :                                "of line %d", i + 1, current_file->line);
    1964              :             }
    1965              : 
    1966          648 :           while (i < 6)
    1967              :             {
    1968          542 :               *buffer++ = ' ';
    1969          542 :               i++;
    1970              :             }
    1971              : 
    1972          106 :           goto next_char;
    1973              :         }
    1974              : 
    1975    289701562 :       *buffer++ = c;
    1976    289701562 :       i++;
    1977              : 
    1978    289701562 :       if (maxlen == 0 || preprocessor_flag)
    1979              :         {
    1980      3112772 :           if (i >= buflen)
    1981              :             {
    1982              :               /* Reallocate line buffer to double size to hold the
    1983              :                 overlong line.  */
    1984          231 :               buflen = buflen * 2;
    1985          231 :               *pbuf = XRESIZEVEC (gfc_char_t, *pbuf, (buflen + 1));
    1986          231 :               buffer = (*pbuf) + i;
    1987              :             }
    1988              :         }
    1989    286588790 :       else if (i >= maxlen)
    1990              :         {
    1991              :           bool trunc_warn = true;
    1992              : 
    1993              :           /* Enhancement, if the very next non-space character is an ampersand
    1994              :              or comment that we would otherwise warn about, don't mark as
    1995              :              truncated.  */
    1996              : 
    1997              :           /* Truncate the rest of the line.  */
    1998       113643 :           for (;;)
    1999              :             {
    2000       113643 :               c = getc (input);
    2001       113643 :               if (c == '\r' || c == ' ')
    2002        48738 :                 continue;
    2003              : 
    2004        64905 :               if (c == '\n' || c == EOF)
    2005              :                 break;
    2006              : 
    2007        56108 :               if (!trunc_warn && c != '!')
    2008              :                 trunc_warn = true;
    2009              : 
    2010        56108 :               if (trunc_warn && ((gfc_current_form == FORM_FIXED && c == '&')
    2011        54407 :                   || c == '!'))
    2012              :                 trunc_warn = false;
    2013              : 
    2014            1 :               if (c == '!')
    2015           65 :                 seen_comment = 1;
    2016              : 
    2017        56108 :               if (trunc_warn && !seen_comment)
    2018         8452 :                 trunc_flag = 1;
    2019              :             }
    2020              : 
    2021         8797 :           c = '\n';
    2022         8797 :           continue;
    2023         8797 :         }
    2024              : 
    2025    286579993 : next_char:
    2026    289703827 :       c = getc (input);
    2027              :     }
    2028              : 
    2029              :   /* Pad lines to the selected line length in fixed form.  */
    2030      6797565 :   if (gfc_current_form == FORM_FIXED
    2031       353313 :       && flag_fixed_line_length != 0
    2032       349287 :       && flag_pad_source
    2033       348465 :       && !preprocessor_flag
    2034       348465 :       && c != EOF)
    2035              :     {
    2036      8129838 :       while (i++ < maxlen)
    2037      7785301 :         *buffer++ = ' ';
    2038              :     }
    2039              : 
    2040      6797565 :   *buffer = '\0';
    2041      6797565 :   *pbuflen = buflen;
    2042              : 
    2043      6797565 :   return trunc_flag;
    2044              : }
    2045              : 
    2046              : 
    2047              : /* Get a gfc_file structure, initialize it and add it to
    2048              :    the file stack.  */
    2049              : 
    2050              : static gfc_file *
    2051        65345 : get_file (const char *name, enum lc_reason reason)
    2052              : {
    2053        65345 :   gfc_file *f;
    2054              : 
    2055        65345 :   f = XCNEW (gfc_file);
    2056              : 
    2057        65345 :   f->filename = xstrdup (name);
    2058              : 
    2059        65345 :   f->next = file_head;
    2060        65345 :   file_head = f;
    2061              : 
    2062        65345 :   f->up = current_file;
    2063        65345 :   if (current_file != NULL)
    2064         2493 :     f->inclusion_line = current_file->line;
    2065              : 
    2066        65345 :   linemap_add (line_table, reason, false, f->filename, 1);
    2067              : 
    2068        65345 :   return f;
    2069              : }
    2070              : 
    2071              : 
    2072              : /* Deal with a line from the C preprocessor. The
    2073              :    initial octothorp has already been seen.  */
    2074              : 
    2075              : static void
    2076         8941 : preprocessor_line (gfc_char_t *c)
    2077              : {
    2078         8941 :   bool flag[5];
    2079         8941 :   int i, line;
    2080         8941 :   gfc_char_t *wide_filename;
    2081         8941 :   gfc_file *f;
    2082         8941 :   int escaped, unescape;
    2083         8941 :   char *filename;
    2084              : 
    2085         8941 :   c++;
    2086        17882 :   while (*c == ' ' || *c == '\t')
    2087         8941 :     c++;
    2088              : 
    2089         8941 :   if (*c < '0' || *c > '9')
    2090            2 :     goto bad_cpp_line;
    2091              : 
    2092         8939 :   line = wide_atoi (c);
    2093              : 
    2094         8939 :   c = wide_strchr (c, ' ');
    2095         8939 :   if (c == NULL)
    2096              :     {
    2097              :       /* No file name given.  Set new line number.  */
    2098            0 :       current_file->line = line;
    2099         8939 :       return;
    2100              :     }
    2101              : 
    2102              :   /* Skip spaces.  */
    2103        17878 :   while (*c == ' ' || *c == '\t')
    2104         8939 :     c++;
    2105              : 
    2106              :   /* Skip quote.  */
    2107         8939 :   if (*c != '"')
    2108            0 :     goto bad_cpp_line;
    2109         8939 :   ++c;
    2110              : 
    2111         8939 :   wide_filename = c;
    2112              : 
    2113              :   /* Make filename end at quote.  */
    2114         8939 :   unescape = 0;
    2115         8939 :   escaped = false;
    2116       427750 :   while (*c && ! (!escaped && *c == '"'))
    2117              :     {
    2118       418797 :       if (escaped)
    2119              :         escaped = false;
    2120       418797 :       else if (*c == '\\')
    2121              :         {
    2122           14 :           escaped = true;
    2123           14 :           unescape++;
    2124              :         }
    2125       418811 :       ++c;
    2126              :     }
    2127              : 
    2128         8939 :   if (! *c)
    2129              :     /* Preprocessor line has no closing quote.  */
    2130            0 :     goto bad_cpp_line;
    2131              : 
    2132         8939 :   *c++ = '\0';
    2133              : 
    2134              :   /* Undo effects of cpp_quote_string.  */
    2135         8939 :   if (unescape)
    2136              :     {
    2137            2 :       gfc_char_t *s = wide_filename;
    2138            2 :       gfc_char_t *d = gfc_get_wide_string (c - wide_filename - unescape);
    2139              : 
    2140            2 :       wide_filename = d;
    2141          118 :       while (*s)
    2142              :         {
    2143          114 :           if (*s == '\\')
    2144           14 :             *d++ = *++s;
    2145              :           else
    2146          100 :             *d++ = *s;
    2147          114 :           s++;
    2148              :         }
    2149            2 :       *d = '\0';
    2150              :     }
    2151              : 
    2152              :   /* Get flags.  */
    2153              : 
    2154         8939 :   flag[1] = flag[2] = flag[3] = flag[4] = false;
    2155              : 
    2156        13200 :   for (;;)
    2157              :     {
    2158        13200 :       c = wide_strchr (c, ' ');
    2159        13200 :       if (c == NULL)
    2160              :         break;
    2161              : 
    2162         4261 :       c++;
    2163         4261 :       i = wide_atoi (c);
    2164              : 
    2165         4261 :       if (i >= 1 && i <= 4)
    2166         4261 :         flag[i] = true;
    2167              :     }
    2168              : 
    2169              :   /* Convert the filename in wide characters into a filename in narrow
    2170              :      characters.  */
    2171         8939 :   filename = gfc_widechar_to_char (wide_filename, -1);
    2172              : 
    2173              :   /* Interpret flags.  */
    2174              : 
    2175         8939 :   if (flag[1]) /* Starting new file.  */
    2176              :     {
    2177         2129 :       f = get_file (filename, LC_RENAME);
    2178         2129 :       add_file_change (f->filename, f->inclusion_line);
    2179         2129 :       current_file = f;
    2180              :     }
    2181              : 
    2182         8939 :   if (flag[2]) /* Ending current file.  */
    2183              :     {
    2184         2130 :       if (!current_file->up
    2185         2130 :           || filename_cmp (current_file->up->filename, filename) != 0)
    2186              :         {
    2187            1 :           linemap_line_start (line_table, current_file->line, 80);
    2188              :           /* ??? One could compute the exact column where the filename
    2189              :              starts and compute the exact location here.  */
    2190            1 :           gfc_warning_now_at (linemap_position_for_column (line_table, 1),
    2191              :                               0, "file %qs left but not entered",
    2192              :                               filename);
    2193            1 :           current_file->line++;
    2194            1 :           if (unescape)
    2195            0 :             free (wide_filename);
    2196            1 :           free (filename);
    2197            1 :           return;
    2198              :         }
    2199              : 
    2200         2129 :       add_file_change (NULL, line);
    2201         2129 :       current_file = current_file->up;
    2202         2129 :       linemap_add (line_table, LC_RENAME, false, current_file->filename,
    2203         2129 :                    current_file->line);
    2204              :     }
    2205              : 
    2206              :   /* The name of the file can be a temporary file produced by
    2207              :      cpp. Replace the name if it is different.  */
    2208              : 
    2209         8938 :   if (filename_cmp (current_file->filename, filename) != 0)
    2210              :     {
    2211              :        /* FIXME: we leak the old filename because a pointer to it may be stored
    2212              :           in the linemap.  Alternative could be using GC or updating linemap to
    2213              :           point to the new name, but there is no API for that currently.  */
    2214         3448 :       current_file->filename = xstrdup (filename);
    2215              : 
    2216              :       /* We need to tell the linemap API that the filename changed.  Just
    2217              :          changing current_file is insufficient.  */
    2218         3448 :       linemap_add (line_table, LC_RENAME, false, current_file->filename, line);
    2219              :     }
    2220              : 
    2221              :   /* Set new line number.  */
    2222         8938 :   current_file->line = line;
    2223         8938 :   if (unescape)
    2224            2 :     free (wide_filename);
    2225         8938 :   free (filename);
    2226         8938 :   return;
    2227              : 
    2228            2 :  bad_cpp_line:
    2229            2 :   linemap_line_start (line_table, current_file->line, 80);
    2230              :   /* ??? One could compute the exact column where the directive
    2231              :      starts and compute the exact location here.  */
    2232            2 :   gfc_warning_now_at (linemap_position_for_column (line_table, 2), 0,
    2233              :                       "Illegal preprocessor directive");
    2234            2 :   current_file->line++;
    2235              : }
    2236              : 
    2237              : 
    2238              : static void load_file (const char *, const char *, bool);
    2239              : 
    2240              : /* include_line()-- Checks a line buffer to see if it is an include
    2241              :    line.  If so, we call load_file() recursively to load the included
    2242              :    file.  We never return a syntax error because a statement like
    2243              :    "include = 5" is perfectly legal.  We return 0 if no include was
    2244              :    processed, 1 if we matched an include or -1 if include was
    2245              :    partially processed, but will need continuation lines.  */
    2246              : 
    2247              : static int
    2248      6725409 : include_line (gfc_char_t *line)
    2249              : {
    2250      6725409 :   gfc_char_t quote, *c, *begin, *stop;
    2251      6725409 :   char *filename;
    2252      6725409 :   const char *include = "include";
    2253      6725409 :   bool allow_continuation = flag_dec_include;
    2254      6725409 :   int i;
    2255              : 
    2256      6725409 :   c = line;
    2257              : 
    2258      6725409 :   if (flag_openmp || flag_openmp_simd)
    2259              :     {
    2260       664921 :       if (gfc_current_form == FORM_FREE)
    2261              :         {
    2262      1424023 :           while (*c == ' ' || *c == '\t')
    2263       792242 :             c++;
    2264       631781 :           if (*c == '!' && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
    2265          265 :             c += 3;
    2266              :         }
    2267              :       else
    2268              :         {
    2269        33140 :           if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
    2270        11252 :               && c[1] == '$' && c[2] == ' ')
    2271           59 :             c += 3;
    2272              :         }
    2273              :     }
    2274              : 
    2275      6725409 :   if (gfc_current_form == FORM_FREE)
    2276              :     {
    2277     10069965 :       while (*c == ' ' || *c == '\t')
    2278      3693847 :         c++;
    2279      6376118 :       if (gfc_wide_strncasecmp (c, "include", 7))
    2280              :         {
    2281      6375836 :           if (!allow_continuation)
    2282              :             return 0;
    2283        37754 :           for (i = 0; i < 7; ++i)
    2284              :             {
    2285        37754 :               gfc_char_t c1 = gfc_wide_tolower (*c);
    2286        37754 :               if (c1 != (unsigned char) include[i])
    2287              :                 break;
    2288         2333 :               c++;
    2289              :             }
    2290        35421 :           if (i == 0 || *c != '&')
    2291              :             return 0;
    2292            2 :           c++;
    2293            4 :           while (*c == ' ' || *c == '\t')
    2294            2 :             c++;
    2295            2 :           if (*c == '\0' || *c == '!')
    2296              :             return -1;
    2297              :           return 0;
    2298              :         }
    2299              : 
    2300          282 :       c += 7;
    2301              :     }
    2302              :   else
    2303              :     {
    2304      2122086 :       while (*c == ' ' || *c == '\t')
    2305      1772795 :         c++;
    2306       349291 :       if (flag_dec_include && *c == '0' && c - line == 5)
    2307              :         {
    2308            6 :           c++;
    2309            6 :           while (*c == ' ' || *c == '\t')
    2310            0 :             c++;
    2311              :         }
    2312       349291 :       if (c - line < 6)
    2313       253960 :         allow_continuation = false;
    2314       388112 :       for (i = 0; i < 7; ++i)
    2315              :         {
    2316       388030 :           gfc_char_t c1 = gfc_wide_tolower (*c);
    2317       388030 :           if (c1 != (unsigned char) include[i])
    2318              :             break;
    2319        38821 :           c++;
    2320        39910 :           while (*c == ' ' || *c == '\t')
    2321         1089 :             c++;
    2322              :         }
    2323       349291 :       if (!allow_continuation)
    2324              :         {
    2325       349107 :           if (i != 7)
    2326              :             return 0;
    2327              :         }
    2328          184 :       else if (i != 7)
    2329              :         {
    2330          173 :           if (i == 0)
    2331              :             return 0;
    2332              : 
    2333              :           /* At the end of line or comment this might be continued.  */
    2334           60 :           if (*c == '\0' || *c == '!')
    2335              :             return -1;
    2336              : 
    2337              :           return 0;
    2338              :         }
    2339              :     }
    2340              : 
    2341          642 :   while (*c == ' ' || *c == '\t')
    2342          278 :     c++;
    2343              : 
    2344              :   /* Find filename between quotes.  */
    2345              : 
    2346          364 :   quote = *c++;
    2347          364 :   if (quote != '"' && quote != '\'')
    2348              :     {
    2349           15 :       if (allow_continuation)
    2350              :         {
    2351           15 :           if (gfc_current_form == FORM_FREE)
    2352              :             {
    2353            8 :               if (quote == '&')
    2354              :                 {
    2355            6 :                   while (*c == ' ' || *c == '\t')
    2356            0 :                     c++;
    2357            6 :                   if (*c == '\0' || *c == '!')
    2358              :                     return -1;
    2359              :                 }
    2360              :             }
    2361            7 :           else if (quote == '\0' || quote == '!')
    2362              :             return -1;
    2363              :         }
    2364              :       return 0;
    2365              :     }
    2366              : 
    2367              :   begin = c;
    2368              : 
    2369              :   bool cont = false;
    2370         7451 :   while (*c != quote && *c != '\0')
    2371              :     {
    2372         7102 :       if (allow_continuation && gfc_current_form == FORM_FREE)
    2373              :         {
    2374         2145 :           if (*c == '&')
    2375              :             cont = true;
    2376         2143 :           else if (*c != ' ' && *c != '\t')
    2377         7102 :             cont = false;
    2378              :         }
    2379         7102 :       c++;
    2380              :     }
    2381              : 
    2382          349 :   if (*c == '\0')
    2383              :     {
    2384            4 :       if (allow_continuation
    2385            4 :           && (cont || gfc_current_form != FORM_FREE))
    2386              :         return -1;
    2387              :       return 0;
    2388              :     }
    2389              : 
    2390          345 :   stop = c++;
    2391              : 
    2392         3505 :   while (*c == ' ' || *c == '\t')
    2393         3160 :     c++;
    2394              : 
    2395          345 :   if (*c != '\0' && *c != '!')
    2396              :     return 0;
    2397              : 
    2398              :   /* We have an include line at this point.  */
    2399              : 
    2400          345 :   *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
    2401              :                    read by anything else.  */
    2402              : 
    2403          345 :   filename = gfc_widechar_to_char (begin, -1);
    2404          345 :   load_file (filename, NULL, false);
    2405          342 :   free (filename);
    2406          342 :   return 1;
    2407              : }
    2408              : 
    2409              : /* Similarly, but try to parse an INCLUDE statement, using gfc_next_char etc.
    2410              :    APIs.  Return 1 if recognized as valid INCLUDE statement and load_file has
    2411              :    been called, 0 if it is not a valid INCLUDE statement and -1 if eof has
    2412              :    been encountered while parsing it.  */
    2413              : static int
    2414           63 : include_stmt (gfc_linebuf *b)
    2415              : {
    2416           63 :   int ret = 0, i, length;
    2417           63 :   const char *include = "include";
    2418           63 :   gfc_char_t c, quote = 0;
    2419           63 :   locus str_locus;
    2420           63 :   char *filename;
    2421              : 
    2422           63 :   continue_flag = 0;
    2423           63 :   end_flag = 0;
    2424           63 :   gcc_attribute_flag = 0;
    2425           63 :   openmp_flag = 0;
    2426           63 :   openacc_flag = 0;
    2427           63 :   continue_count = 0;
    2428           63 :   continue_line = 0;
    2429           63 :   gfc_current_locus.u.lb = b;
    2430           63 :   gfc_current_locus.nextc = b->line;
    2431              : 
    2432           63 :   gfc_skip_comments ();
    2433           63 :   gfc_gobble_whitespace ();
    2434              : 
    2435          509 :   for (i = 0; i < 7; i++)
    2436              :     {
    2437          405 :       c = gfc_next_char ();
    2438          405 :       if (c != (unsigned char) include[i])
    2439              :         {
    2440           30 :           if (gfc_current_form == FORM_FIXED
    2441           28 :               && i == 0
    2442           28 :               && c == '0'
    2443            8 :               && gfc_current_locus.nextc == b->line + 6)
    2444              :             {
    2445            8 :               gfc_gobble_whitespace ();
    2446            8 :               i--;
    2447            8 :               continue;
    2448              :             }
    2449           22 :           gcc_assert (i != 0);
    2450           22 :           if (c == '\n')
    2451              :             {
    2452           22 :               gfc_advance_line ();
    2453           22 :               gfc_skip_comments ();
    2454           22 :               if (gfc_at_eof ())
    2455           22 :                 ret = -1;
    2456              :             }
    2457           22 :           goto do_ret;
    2458              :         }
    2459              :     }
    2460           41 :   gfc_gobble_whitespace ();
    2461              : 
    2462           41 :   c = gfc_next_char ();
    2463           41 :   if (c == '\'' || c == '"')
    2464           30 :     quote = c;
    2465              :   else
    2466              :     {
    2467           11 :       if (c == '\n')
    2468              :         {
    2469           10 :           gfc_advance_line ();
    2470           10 :           gfc_skip_comments ();
    2471           10 :           if (gfc_at_eof ())
    2472           11 :             ret = -1;
    2473              :         }
    2474           11 :       goto do_ret;
    2475              :     }
    2476              : 
    2477           30 :   str_locus = gfc_current_locus;
    2478           30 :   length = 0;
    2479          710 :   do
    2480              :     {
    2481          370 :       c = gfc_next_char_literal (INSTRING_NOWARN);
    2482          370 :       if (c == quote)
    2483              :         break;
    2484          348 :       if (c == '\n')
    2485              :         {
    2486            8 :           gfc_advance_line ();
    2487            8 :           gfc_skip_comments ();
    2488            8 :           if (gfc_at_eof ())
    2489            8 :             ret = -1;
    2490            8 :           goto do_ret;
    2491              :         }
    2492          340 :       length++;
    2493              :     }
    2494              :   while (1);
    2495              : 
    2496           22 :   gfc_gobble_whitespace ();
    2497           22 :   c = gfc_next_char ();
    2498           22 :   if (c != '\n')
    2499            0 :     goto do_ret;
    2500              : 
    2501           22 :   gfc_current_locus = str_locus;
    2502           22 :   ret = 1;
    2503           22 :   filename = XNEWVEC (char, length + 1);
    2504          343 :   for (i = 0; i < length; i++)
    2505              :     {
    2506          299 :       c = gfc_next_char_literal (INSTRING_WARN);
    2507          299 :       gcc_assert (gfc_wide_fits_in_byte (c));
    2508          299 :       filename[i] = (unsigned char) c;
    2509              :     }
    2510           22 :   filename[length] = '\0';
    2511           22 :   load_file (filename, NULL, false);
    2512           22 :   free (filename);
    2513              : 
    2514           63 : do_ret:
    2515           63 :   continue_flag = 0;
    2516           63 :   end_flag = 0;
    2517           63 :   gcc_attribute_flag = 0;
    2518           63 :   openmp_flag = 0;
    2519           63 :   openacc_flag = 0;
    2520           63 :   continue_count = 0;
    2521           63 :   continue_line = 0;
    2522           63 :   memset (&gfc_current_locus, '\0', sizeof (locus));
    2523           63 :   memset (&openmp_locus, '\0', sizeof (locus));
    2524           63 :   memset (&openacc_locus, '\0', sizeof (locus));
    2525           63 :   memset (&gcc_attribute_locus, '\0', sizeof (locus));
    2526           63 :   return ret;
    2527              : }
    2528              : 
    2529              : 
    2530              : 
    2531              : /* Load a file into memory by calling load_line until the file ends.  */
    2532              : 
    2533              : static void
    2534        63219 : load_file (const char *realfilename, const char *displayedname, bool initial)
    2535              : {
    2536        63219 :   gfc_char_t *line;
    2537        63219 :   gfc_linebuf *b, *include_b = NULL;
    2538        63219 :   gfc_file *f;
    2539        63219 :   FILE *input;
    2540        63219 :   int len, line_len;
    2541        63219 :   bool first_line;
    2542        63219 :   struct stat st;
    2543        63219 :   int stat_result;
    2544        63219 :   const char *filename;
    2545              :   /* If realfilename and displayedname are different and non-null then
    2546              :      surely realfilename is the preprocessed form of
    2547              :      displayedname.  */
    2548       188517 :   bool preprocessed_p = (realfilename && displayedname
    2549        63219 :                          && strcmp (realfilename, displayedname));
    2550              : 
    2551        62079 :   filename = displayedname ? displayedname : realfilename;
    2552              : 
    2553        63589 :   for (f = current_file; f; f = f->up)
    2554          370 :     if (filename_cmp (filename, f->filename) == 0)
    2555            0 :       fatal_error (linemap_line_start (line_table, current_file->line, 0),
    2556              :                    "File %qs is being included recursively", filename);
    2557        63219 :   if (initial)
    2558              :     {
    2559        31427 :       if (gfc_src_file)
    2560              :         {
    2561            4 :           input = gfc_src_file;
    2562            4 :           gfc_src_file = NULL;
    2563              :         }
    2564              :       else
    2565        31423 :         input = gfc_open_file (realfilename);
    2566              : 
    2567        31427 :       if (input == NULL)
    2568            0 :         gfc_fatal_error ("Cannot open file %qs", filename);
    2569              :     }
    2570              :   else
    2571              :     {
    2572        31792 :       input = gfc_open_included_file (realfilename, false, false);
    2573        31792 :       if (input == NULL)
    2574              :         {
    2575              :           /* For -fpre-include file, current_file is NULL.  */
    2576            1 :           if (current_file)
    2577            1 :             fatal_error (linemap_line_start (line_table, current_file->line, 0),
    2578              :                          "Cannot open included file %qs", filename);
    2579              :           else
    2580            0 :             gfc_fatal_error ("Cannot open pre-included file %qs", filename);
    2581              :         }
    2582        31791 :       stat_result = stat (realfilename, &st);
    2583        31791 :       if (stat_result == 0 && !S_ISREG (st.st_mode))
    2584              :         {
    2585            2 :           fclose (input);
    2586            2 :           if (current_file)
    2587            2 :             fatal_error (linemap_line_start (line_table, current_file->line, 0),
    2588              :                          "Included file %qs is not a regular file", filename);
    2589              :           else
    2590            0 :             gfc_fatal_error ("Included file %qs is not a regular file", filename);
    2591              :         }
    2592              :     }
    2593              : 
    2594              :   /* Load the file.
    2595              : 
    2596              :      A "non-initial" file means a file that is being included.  In
    2597              :      that case we are creating an LC_ENTER map.
    2598              : 
    2599              :      An "initial" file means a main file; one that is not included.
    2600              :      That file has already got at least one (surely more) line map(s)
    2601              :      created by gfc_init.  So the subsequent map created in that case
    2602              :      must have LC_RENAME reason.
    2603              : 
    2604              :      This latter case is not true for a preprocessed file.  In that
    2605              :      case, although the file is "initial", the line maps created by
    2606              :      gfc_init was used during the preprocessing of the file.  Now that
    2607              :      the preprocessing is over and we are being fed the result of that
    2608              :      preprocessing, we need to create a brand new line map for the
    2609              :      preprocessed file, so the reason is going to be LC_ENTER.  */
    2610              : 
    2611        96145 :   f = get_file (filename, (initial && !preprocessed_p) ? LC_RENAME : LC_ENTER);
    2612        63216 :   if (!initial)
    2613        31789 :     add_file_change (f->filename, f->inclusion_line);
    2614        63216 :   current_file = f;
    2615        63216 :   current_file->line = 1;
    2616        63216 :   line = NULL;
    2617        63216 :   line_len = 0;
    2618        63216 :   first_line = true;
    2619              : 
    2620        63216 :   if (initial && gfc_src_preprocessor_lines[0])
    2621              :     {
    2622            4 :       preprocessor_line (gfc_src_preprocessor_lines[0]);
    2623            4 :       free (gfc_src_preprocessor_lines[0]);
    2624            4 :       gfc_src_preprocessor_lines[0] = NULL;
    2625            4 :       if (gfc_src_preprocessor_lines[1])
    2626              :         {
    2627            4 :           preprocessor_line (gfc_src_preprocessor_lines[1]);
    2628            4 :           free (gfc_src_preprocessor_lines[1]);
    2629            4 :           gfc_src_preprocessor_lines[1] = NULL;
    2630              :         }
    2631              :     }
    2632              : 
    2633      6797555 :   for (;;)
    2634              :     {
    2635      6797555 :       int trunc = load_line (input, &line, &line_len, NULL);
    2636      6797555 :       int inc_line;
    2637              : 
    2638      6797555 :       len = gfc_wide_strlen (line);
    2639      6797555 :       if (feof (input) && len == 0)
    2640              :         break;
    2641              : 
    2642              :       /* If this is the first line of the file, it can contain a byte
    2643              :          order mark (BOM), which we will ignore:
    2644              :            FF FE is UTF-16 little endian,
    2645              :            FE FF is UTF-16 big endian,
    2646              :            EF BB BF is UTF-8.  */
    2647      6734342 :       if (first_line
    2648        67789 :           && ((line_len >= 2 && line[0] == (unsigned char) '\xFF'
    2649            3 :                              && line[1] == (unsigned char) '\xFE')
    2650        67786 :               || (line_len >= 2 && line[0] == (unsigned char) '\xFE'
    2651            1 :                                 && line[1] == (unsigned char) '\xFF')
    2652        67785 :               || (line_len >= 3 && line[0] == (unsigned char) '\xEF'
    2653            2 :                                 && line[1] == (unsigned char) '\xBB'
    2654            2 :                                 && line[2] == (unsigned char) '\xBF')))
    2655              :         {
    2656            6 :           int n = line[1] == (unsigned char) '\xBB' ? 3 : 2;
    2657            6 :           gfc_char_t *new_char = gfc_get_wide_string (line_len);
    2658              : 
    2659            6 :           wide_strcpy (new_char, &line[n]);
    2660            6 :           free (line);
    2661            6 :           line = new_char;
    2662            6 :           len -= n;
    2663              :         }
    2664              : 
    2665              :       /* There are three things this line can be: a line of Fortran
    2666              :          source, an include line or a C preprocessor directive.  */
    2667              : 
    2668      6734342 :       if (line[0] == '#')
    2669              :         {
    2670              :           /* When -g3 is specified, it's possible that we emit #define
    2671              :              and #undef lines, which we need to pass to the middle-end
    2672              :              so that it can emit correct debug info.  */
    2673        17874 :           if (debug_info_level == DINFO_LEVEL_VERBOSE
    2674         8941 :               && (wide_strncmp (line, "#define ", 8) == 0
    2675           28 :                   || wide_strncmp (line, "#undef ", 7) == 0))
    2676              :             ;
    2677              :           else
    2678              :             {
    2679         8933 :               preprocessor_line (line);
    2680         8933 :               continue;
    2681              :             }
    2682              :         }
    2683              : 
    2684              :       /* Preprocessed files have preprocessor lines added before the byte
    2685              :          order mark, so first_line is not about the first line of the file
    2686              :          but the first line that's not a preprocessor line.  */
    2687      6725409 :       first_line = false;
    2688              : 
    2689      6725409 :       inc_line = include_line (line);
    2690      6725406 :       if (inc_line > 0)
    2691              :         {
    2692          342 :           current_file->line++;
    2693          342 :           continue;
    2694              :         }
    2695              : 
    2696              :       /* Add line.  */
    2697              : 
    2698      6725064 :       b = XCNEWVAR (gfc_linebuf, gfc_linebuf_header_size
    2699              :                     + (len + 1) * sizeof (gfc_char_t));
    2700              : 
    2701              : 
    2702      6725064 :       b->location
    2703      6725064 :         = linemap_line_start (line_table, current_file->line++, len);
    2704              :       /* ??? We add the location for the maximum column possible here,
    2705              :          because otherwise if the next call creates a new line-map, it
    2706              :          will not reserve space for any offset.  */
    2707      6725064 :       if (len > 0)
    2708      5578265 :         linemap_position_for_column (line_table, len);
    2709              : 
    2710      6725064 :       b->file = current_file;
    2711      6725064 :       b->truncated = trunc;
    2712      6725064 :       wide_strcpy (b->line, line);
    2713              : 
    2714      6725064 :       if (line_head == NULL)
    2715        31427 :         line_head = b;
    2716              :       else
    2717      6693637 :         line_tail->next = b;
    2718              : 
    2719      6725064 :       line_tail = b;
    2720              : 
    2721      6792819 :       while (file_changes_cur < file_changes_count)
    2722        67755 :         file_changes[file_changes_cur++].lb = b;
    2723              : 
    2724      6725064 :       if (flag_dec_include)
    2725              :         {
    2726        37104 :           if (include_b && b != include_b)
    2727              :             {
    2728           63 :               int inc_line2 = include_stmt (include_b);
    2729           63 :               if (inc_line2 == 0)
    2730              :                 include_b = NULL;
    2731           62 :               else if (inc_line2 > 0)
    2732              :                 {
    2733          146 :                   do
    2734              :                     {
    2735           84 :                       if (gfc_current_form == FORM_FIXED)
    2736              :                         {
    2737         3650 :                           for (gfc_char_t *p = include_b->line; *p; p++)
    2738         3600 :                             *p = ' ';
    2739              :                         }
    2740              :                       else
    2741           34 :                         include_b->line[0] = '\0';
    2742           84 :                       if (include_b == b)
    2743              :                         break;
    2744           62 :                       include_b = include_b->next;
    2745           62 :                     }
    2746              :                   while (1);
    2747              :                   include_b = NULL;
    2748              :                 }
    2749              :             }
    2750        37104 :           if (inc_line == -1 && !include_b)
    2751           23 :             include_b = b;
    2752              :         }
    2753              :     }
    2754              : 
    2755              :   /* Release the line buffer allocated in load_line.  */
    2756        63213 :   free (line);
    2757              : 
    2758        63213 :   fclose (input);
    2759              : 
    2760        63213 :   if (!initial)
    2761        31789 :     add_file_change (NULL, current_file->inclusion_line + 1);
    2762        63213 :   current_file = current_file->up;
    2763        63213 :   linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
    2764        63213 : }
    2765              : 
    2766              : 
    2767              : /* Open a new file and start scanning from that file. Returns true
    2768              :    if everything went OK, false otherwise.  If form == FORM_UNKNOWN
    2769              :    it tries to determine the source form from the filename, defaulting
    2770              :    to free form.  */
    2771              : 
    2772              : void
    2773        31441 : gfc_new_file (void)
    2774              : {
    2775        31441 :   if (flag_pre_include != NULL)
    2776        31425 :     load_file (flag_pre_include, NULL, false);
    2777              : 
    2778        31441 :   if (gfc_cpp_enabled ())
    2779              :     {
    2780         1155 :       if (gfc_cpp_preprocess (gfc_source_file))
    2781              :         {
    2782         1153 :           if (!gfc_cpp_preprocess_only ())
    2783         1140 :             load_file (gfc_cpp_temporary_file (), gfc_source_file, true);
    2784              :         }
    2785              :       else
    2786            1 :         load_file (gfc_source_file, NULL, true);
    2787              :     }
    2788              :   else
    2789        30286 :     load_file (gfc_source_file, NULL, true);
    2790              : 
    2791        31437 :   gfc_current_locus.u.lb = line_head;
    2792        31437 :   gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
    2793              : 
    2794              : #if 0 /* Debugging aid.  */
    2795              :   for (; line_head; line_head = line_head->next)
    2796              :     printf ("%s:%3d %s\n", LOCATION_FILE (line_head->location),
    2797              :             LOCATION_LINE (line_head->location), line_head->line);
    2798              : 
    2799              :   exit (SUCCESS_EXIT_CODE);
    2800              : #endif
    2801        31437 : }
    2802              : 
    2803              : static char *
    2804           10 : unescape_filename (const char *ptr)
    2805              : {
    2806           10 :   const char *p = ptr, *s;
    2807           10 :   char *d, *ret;
    2808           10 :   int escaped, unescape = 0;
    2809              : 
    2810              :   /* Make filename end at quote.  */
    2811           10 :   escaped = false;
    2812          284 :   while (*p && ! (! escaped && *p == '"'))
    2813              :     {
    2814          260 :       if (escaped)
    2815              :         escaped = false;
    2816          260 :       else if (*p == '\\')
    2817              :         {
    2818           14 :           escaped = true;
    2819           14 :           unescape++;
    2820              :         }
    2821          274 :       ++p;
    2822              :     }
    2823              : 
    2824           10 :   if (!*p || p[1])
    2825              :     return NULL;
    2826              : 
    2827              :   /* Undo effects of cpp_quote_string.  */
    2828           10 :   s = ptr;
    2829           10 :   d = XCNEWVEC (char, p + 1 - ptr - unescape);
    2830           10 :   ret = d;
    2831              : 
    2832          280 :   while (s != p)
    2833              :     {
    2834          260 :       if (*s == '\\')
    2835           14 :         *d++ = *++s;
    2836              :       else
    2837          246 :         *d++ = *s;
    2838          260 :       s++;
    2839              :     }
    2840           10 :   *d = '\0';
    2841           10 :   return ret;
    2842              : }
    2843              : 
    2844              : /* For preprocessed files, if the first tokens are of the form # NUM.
    2845              :    handle the directives so we know the original file name.  */
    2846              : 
    2847              : const char *
    2848            5 : gfc_read_orig_filename (const char *filename, const char **canon_source_file)
    2849              : {
    2850            5 :   int c, len;
    2851            5 :   char *dirname, *tmp;
    2852              : 
    2853            5 :   gfc_src_file = gfc_open_file (filename);
    2854            5 :   if (gfc_src_file == NULL)
    2855              :     return NULL;
    2856              : 
    2857            5 :   c = getc (gfc_src_file);
    2858              : 
    2859            5 :   if (c != '#')
    2860              :     return NULL;
    2861              : 
    2862            5 :   len = 0;
    2863            5 :   load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len, &c);
    2864              : 
    2865            5 :   if (wide_strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
    2866              :     return NULL;
    2867              : 
    2868            5 :   tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[0][5], -1);
    2869            5 :   filename = unescape_filename (tmp);
    2870            5 :   free (tmp);
    2871            5 :   if (filename == NULL)
    2872              :     return NULL;
    2873              : 
    2874            5 :   c = getc (gfc_src_file);
    2875              : 
    2876            5 :   if (c != '#')
    2877              :     return filename;
    2878              : 
    2879            5 :   len = 0;
    2880            5 :   load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len, &c);
    2881              : 
    2882            5 :   if (wide_strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
    2883              :     return filename;
    2884              : 
    2885            5 :   tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[1][5], -1);
    2886            5 :   dirname = unescape_filename (tmp);
    2887            5 :   free (tmp);
    2888            5 :   if (dirname == NULL)
    2889              :     return filename;
    2890              : 
    2891            5 :   len = strlen (dirname);
    2892            5 :   if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
    2893              :     {
    2894            3 :       free (dirname);
    2895            3 :       return filename;
    2896              :     }
    2897            2 :   dirname[len - 2] = '\0';
    2898            2 :   set_src_pwd (dirname);
    2899              : 
    2900            2 :   if (! IS_ABSOLUTE_PATH (filename))
    2901              :     {
    2902            2 :       char *p = XCNEWVEC (char, len + strlen (filename));
    2903              : 
    2904            2 :       memcpy (p, dirname, len - 2);
    2905            2 :       p[len - 2] = '/';
    2906            2 :       strcpy (p + len - 1, filename);
    2907            2 :       *canon_source_file = p;
    2908              :     }
    2909              : 
    2910            2 :   free (dirname);
    2911            2 :   return filename;
    2912              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.