LCOV - code coverage report
Current view: top level - gcc/fortran - module.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.1 % 3895 3626
Test Date: 2026-02-28 14:20:25 Functions: 99.3 % 148 147
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Handle modules, which amounts to loading and saving symbols and
       2              :    their attendant structures.
       3              :    Copyright (C) 2000-2026 Free Software Foundation, Inc.
       4              :    Contributed by Andy Vaught
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : /* The syntax of gfortran modules resembles that of lisp lists, i.e. a
      23              :    sequence of atoms, which can be left or right parenthesis, names,
      24              :    integers or strings.  Parenthesis are always matched which allows
      25              :    us to skip over sections at high speed without having to know
      26              :    anything about the internal structure of the lists.  A "name" is
      27              :    usually a fortran 95 identifier, but can also start with '@' in
      28              :    order to reference a hidden symbol.
      29              : 
      30              :    The first line of a module is an informational message about what
      31              :    created the module, the file it came from and when it was created.
      32              :    The second line is a warning for people not to edit the module.
      33              :    The rest of the module looks like:
      34              : 
      35              :    ( ( <Interface info for UPLUS> )
      36              :      ( <Interface info for UMINUS> )
      37              :      ...
      38              :    )
      39              :    ( ( <name of operator interface> <module of op interface> <i/f1> ... )
      40              :      ...
      41              :    )
      42              :    ( ( <name of generic interface> <module of generic interface> <i/f1> ... )
      43              :      ...
      44              :    )
      45              :    ( ( <common name> <symbol> <saved flag>)
      46              :      ...
      47              :    )
      48              : 
      49              :    ( equivalence list )
      50              : 
      51              :    ( <Symbol Number (in no particular order)>
      52              :      <True name of symbol>
      53              :      <Module name of symbol>
      54              :      ( <symbol information> )
      55              :      ...
      56              :    )
      57              :    ( <Symtree name>
      58              :      <Ambiguous flag>
      59              :      <Symbol number>
      60              :      ...
      61              :    )
      62              : 
      63              :    In general, symbols refer to other symbols by their symbol number,
      64              :    which are zero based.  Symbols are written to the module in no
      65              :    particular order.  */
      66              : 
      67              : #include "config.h"
      68              : #include "system.h"
      69              : #include "coretypes.h"
      70              : #include "options.h"
      71              : #include "tree.h"
      72              : #include "gfortran.h"
      73              : #include "stringpool.h"
      74              : #include "arith.h"
      75              : #include "match.h"
      76              : #include "parse.h" /* FIXME */
      77              : #include "constructor.h"
      78              : #include "cpp.h"
      79              : #include "scanner.h"
      80              : #include <zlib.h>
      81              : 
      82              : #define MODULE_EXTENSION ".mod"
      83              : #define SUBMODULE_EXTENSION ".smod"
      84              : 
      85              : /* Don't put any single quote (') in MOD_VERSION, if you want it to be
      86              :    recognized.  */
      87              : #define MOD_VERSION "16"
      88              : /* Older mod versions we can still parse.  */
      89              : #define COMPAT_MOD_VERSIONS { "15" }
      90              : 
      91              : 
      92              : /* Structure that describes a position within a module file.  */
      93              : 
      94              : typedef struct
      95              : {
      96              :   int column, line;
      97              :   long pos;
      98              : }
      99              : module_locus;
     100              : 
     101              : /* Structure for list of symbols of intrinsic modules.  */
     102              : typedef struct
     103              : {
     104              :   int id;
     105              :   const char *name;
     106              :   int value;
     107              :   int standard;
     108              : }
     109              : intmod_sym;
     110              : 
     111              : 
     112              : typedef enum
     113              : {
     114              :   P_UNKNOWN = 0, P_OTHER, P_NAMESPACE, P_COMPONENT, P_SYMBOL
     115              : }
     116              : pointer_t;
     117              : 
     118              : /* The fixup structure lists pointers to pointers that have to
     119              :    be updated when a pointer value becomes known.  */
     120              : 
     121              : typedef struct fixup_t
     122              : {
     123              :   void **pointer;
     124              :   struct fixup_t *next;
     125              : }
     126              : fixup_t;
     127              : 
     128              : 
     129              : /* Structure for holding extra info needed for pointers being read.  */
     130              : 
     131              : enum gfc_rsym_state
     132              : {
     133              :   UNUSED,
     134              :   NEEDED,
     135              :   USED
     136              : };
     137              : 
     138              : enum gfc_wsym_state
     139              : {
     140              :   UNREFERENCED = 0,
     141              :   NEEDS_WRITE,
     142              :   WRITTEN
     143              : };
     144              : 
     145              : typedef struct pointer_info
     146              : {
     147              :   BBT_HEADER (pointer_info);
     148              :   HOST_WIDE_INT integer;
     149              :   pointer_t type;
     150              : 
     151              :   /* The first component of each member of the union is the pointer
     152              :      being stored.  */
     153              : 
     154              :   fixup_t *fixup;
     155              : 
     156              :   union
     157              :   {
     158              :     void *pointer;      /* Member for doing pointer searches.  */
     159              : 
     160              :     struct
     161              :     {
     162              :       gfc_symbol *sym;
     163              :       char *true_name, *module, *binding_label;
     164              :       fixup_t *stfixup;
     165              :       gfc_symtree *symtree;
     166              :       enum gfc_rsym_state state;
     167              :       int ns, referenced, renamed;
     168              :       module_locus where;
     169              :     }
     170              :     rsym;
     171              : 
     172              :     struct
     173              :     {
     174              :       gfc_symbol *sym;
     175              :       enum gfc_wsym_state state;
     176              :     }
     177              :     wsym;
     178              :   }
     179              :   u;
     180              : 
     181              : }
     182              : pointer_info;
     183              : 
     184              : #define gfc_get_pointer_info() XCNEW (pointer_info)
     185              : 
     186              : 
     187              : /* Local variables */
     188              : 
     189              : /* The gzFile for the module we're reading or writing.  */
     190              : static gzFile module_fp;
     191              : 
     192              : /* Fully qualified module path */
     193              : static char *module_fullpath = NULL;
     194              : 
     195              : /* The name of the module we're reading (USE'ing) or writing.  */
     196              : static const char *module_name;
     197              : /* The name of the .smod file that the submodule will write to.  */
     198              : static const char *submodule_name;
     199              : 
     200              : /* The list of use statements to apply to the current namespace
     201              :    before parsing the non-use statements.  */
     202              : static gfc_use_list *module_list;
     203              : /* The end of the MODULE_LIST list above at the time the recognition
     204              :    of the current statement started.  */
     205              : static gfc_use_list **old_module_list_tail;
     206              : 
     207              : /* If we're reading an intrinsic module, this is its ID.  */
     208              : static intmod_id current_intmod;
     209              : 
     210              : /* Content of module.  */
     211              : static char* module_content;
     212              : 
     213              : static long module_pos;
     214              : static int module_line, module_column, only_flag;
     215              : static int prev_module_line, prev_module_column;
     216              : 
     217              : static enum
     218              : { IO_INPUT, IO_OUTPUT }
     219              : iomode;
     220              : 
     221              : static gfc_use_rename *gfc_rename_list;
     222              : static pointer_info *pi_root;
     223              : static int symbol_number;       /* Counter for assigning symbol numbers */
     224              : 
     225              : /* Tells mio_expr_ref to make symbols for unused equivalence members.  */
     226              : static bool in_load_equiv;
     227              : 
     228              : 
     229              : 
     230              : /*****************************************************************/
     231              : 
     232              : /* Pointer/integer conversion.  Pointers between structures are stored
     233              :    as integers in the module file.  The next couple of subroutines
     234              :    handle this translation for reading and writing.  */
     235              : 
     236              : /* Recursively free the tree of pointer structures.  */
     237              : 
     238              : static void
     239      4073683 : free_pi_tree (pointer_info *p)
     240              : {
     241      4073683 :   if (p == NULL)
     242              :     return;
     243              : 
     244      2025410 :   if (p->fixup != NULL)
     245            0 :     gfc_internal_error ("free_pi_tree(): Unresolved fixup");
     246              : 
     247      2025410 :   free_pi_tree (p->left);
     248      2025410 :   free_pi_tree (p->right);
     249              : 
     250      2025410 :   if (iomode == IO_INPUT)
     251              :     {
     252      1630440 :       XDELETEVEC (p->u.rsym.true_name);
     253      1630440 :       XDELETEVEC (p->u.rsym.module);
     254      1630440 :       XDELETEVEC (p->u.rsym.binding_label);
     255              :     }
     256              : 
     257      2025410 :   free (p);
     258              : }
     259              : 
     260              : 
     261              : /* Compare pointers when searching by pointer.  Used when writing a
     262              :    module.  */
     263              : 
     264              : static int
     265      2319121 : compare_pointers (void *_sn1, void *_sn2)
     266              : {
     267      2319121 :   pointer_info *sn1, *sn2;
     268              : 
     269      2319121 :   sn1 = (pointer_info *) _sn1;
     270      2319121 :   sn2 = (pointer_info *) _sn2;
     271              : 
     272      2319121 :   if (sn1->u.pointer < sn2->u.pointer)
     273              :     return -1;
     274      1355789 :   if (sn1->u.pointer > sn2->u.pointer)
     275      1355789 :     return 1;
     276              : 
     277              :   return 0;
     278              : }
     279              : 
     280              : 
     281              : /* Compare integers when searching by integer.  Used when reading a
     282              :    module.  */
     283              : 
     284              : static int
     285     75850249 : compare_integers (void *_sn1, void *_sn2)
     286              : {
     287     75850249 :   pointer_info *sn1, *sn2;
     288              : 
     289     75850249 :   sn1 = (pointer_info *) _sn1;
     290     75850249 :   sn2 = (pointer_info *) _sn2;
     291              : 
     292     12563790 :   if (sn1->integer < sn2->integer)
     293              :     return -1;
     294     35371117 :   if (sn1->integer > sn2->integer)
     295      8556042 :     return 1;
     296              : 
     297              :   return 0;
     298              : }
     299              : 
     300              : 
     301              : /* Initialize the pointer_info tree.  */
     302              : 
     303              : static void
     304        22863 : init_pi_tree (void)
     305              : {
     306        22863 :   compare_fn compare;
     307        22863 :   pointer_info *p;
     308              : 
     309        22863 :   pi_root = NULL;
     310        22863 :   compare = (iomode == IO_INPUT) ? compare_integers : compare_pointers;
     311              : 
     312              :   /* Pointer 0 is the NULL pointer.  */
     313        22863 :   p = gfc_get_pointer_info ();
     314        22863 :   p->u.pointer = NULL;
     315        22863 :   p->integer = 0;
     316        22863 :   p->type = P_OTHER;
     317              : 
     318        22863 :   gfc_insert_bbt (&pi_root, p, compare);
     319              : 
     320              :   /* Pointer 1 is the current namespace.  */
     321        22863 :   p = gfc_get_pointer_info ();
     322        22863 :   p->u.pointer = gfc_current_ns;
     323        22863 :   p->integer = 1;
     324        22863 :   p->type = P_NAMESPACE;
     325              : 
     326        22863 :   gfc_insert_bbt (&pi_root, p, compare);
     327              : 
     328        22863 :   symbol_number = 2;
     329        22863 : }
     330              : 
     331              : 
     332              : /* During module writing, call here with a pointer to something,
     333              :    returning the pointer_info node.  */
     334              : 
     335              : static pointer_info *
     336      1929649 : find_pointer (void *gp)
     337              : {
     338      1929649 :   pointer_info *p;
     339              : 
     340      1929649 :   p = pi_root;
     341     10221097 :   while (p != NULL)
     342              :     {
     343      9845287 :       if (p->u.pointer == gp)
     344              :         break;
     345      8291448 :       p = (gp < p->u.pointer) ? p->left : p->right;
     346              :     }
     347              : 
     348      1929649 :   return p;
     349              : }
     350              : 
     351              : 
     352              : /* Given a pointer while writing, returns the pointer_info tree node,
     353              :    creating it if it doesn't exist.  */
     354              : 
     355              : static pointer_info *
     356      1807473 : get_pointer (void *gp)
     357              : {
     358      1807473 :   pointer_info *p;
     359              : 
     360      1807473 :   p = find_pointer (gp);
     361      1807473 :   if (p != NULL)
     362              :     return p;
     363              : 
     364              :   /* Pointer doesn't have an integer.  Give it one.  */
     365       375810 :   p = gfc_get_pointer_info ();
     366              : 
     367       375810 :   p->u.pointer = gp;
     368       375810 :   p->integer = symbol_number++;
     369              : 
     370       375810 :   gfc_insert_bbt (&pi_root, p, compare_pointers);
     371              : 
     372       375810 :   return p;
     373              : }
     374              : 
     375              : 
     376              : /* Given an integer during reading, find it in the pointer_info tree,
     377              :    creating the node if not found.  */
     378              : 
     379              : static pointer_info *
     380      8364597 : get_integer (HOST_WIDE_INT integer)
     381              : {
     382      8364597 :   pointer_info *p, t;
     383      8364597 :   int c;
     384              : 
     385      8364597 :   t.integer = integer;
     386              : 
     387      8364597 :   p = pi_root;
     388     64890333 :   while (p != NULL)
     389              :     {
     390     63286459 :       c = compare_integers (&t, p);
     391              :       if (c == 0)
     392              :         break;
     393              : 
     394     56525736 :       p = (c < 0) ? p->left : p->right;
     395              :     }
     396              : 
     397      8364597 :   if (p != NULL)
     398              :     return p;
     399              : 
     400      1603874 :   p = gfc_get_pointer_info ();
     401      1603874 :   p->integer = integer;
     402      1603874 :   p->u.pointer = NULL;
     403              : 
     404      1603874 :   gfc_insert_bbt (&pi_root, p, compare_integers);
     405              : 
     406      1603874 :   return p;
     407              : }
     408              : 
     409              : 
     410              : /* Resolve any fixups using a known pointer.  */
     411              : 
     412              : static void
     413      1652920 : resolve_fixups (fixup_t *f, void *gp)
     414              : {
     415      1652920 :   fixup_t *next;
     416              : 
     417      2489930 :   for (; f; f = next)
     418              :     {
     419       837010 :       next = f->next;
     420       837010 :       *(f->pointer) = gp;
     421       837010 :       free (f);
     422              :     }
     423      1652920 : }
     424              : 
     425              : 
     426              : /* Convert a string such that it starts with a lower-case character. Used
     427              :    to convert the symtree name of a derived-type to the symbol name or to
     428              :    the name of the associated generic function.  */
     429              : 
     430              : const char *
     431      1023592 : gfc_dt_lower_string (const char *name)
     432              : {
     433      1023592 :   if (name[0] != (char) TOLOWER ((unsigned char) name[0]))
     434        61583 :     return gfc_get_string ("%c%s", (char) TOLOWER ((unsigned char) name[0]),
     435        61583 :                            &name[1]);
     436       962009 :   return gfc_get_string ("%s", name);
     437              : }
     438              : 
     439              : 
     440              : /* Convert a string such that it starts with an upper-case character. Used to
     441              :    return the symtree-name for a derived type; the symbol name itself and the
     442              :    symtree/symbol name of the associated generic function start with a lower-
     443              :    case character.  */
     444              : 
     445              : const char *
     446      1492125 : gfc_dt_upper_string (const char *name)
     447              : {
     448      1492125 :   if (name[0] != (char) TOUPPER ((unsigned char) name[0]))
     449      1468041 :     return gfc_get_string ("%c%s", (char) TOUPPER ((unsigned char) name[0]),
     450      1468041 :                            &name[1]);
     451        24084 :   return gfc_get_string ("%s", name);
     452              : }
     453              : 
     454              : /* Call here during module reading when we know what pointer to
     455              :    associate with an integer.  Any fixups that exist are resolved at
     456              :    this time.  */
     457              : 
     458              : static void
     459      1007665 : associate_integer_pointer (pointer_info *p, void *gp)
     460              : {
     461      1007665 :   if (p->u.pointer != NULL)
     462            0 :     gfc_internal_error ("associate_integer_pointer(): Already associated");
     463              : 
     464      1007665 :   p->u.pointer = gp;
     465              : 
     466      1007665 :   resolve_fixups (p->fixup, gp);
     467              : 
     468      1007665 :   p->fixup = NULL;
     469      1007665 : }
     470              : 
     471              : 
     472              : /* During module reading, given an integer and a pointer to a pointer,
     473              :    either store the pointer from an already-known value or create a
     474              :    fixup structure in order to store things later.  Returns zero if
     475              :    the reference has been actually stored, or nonzero if the reference
     476              :    must be fixed later (i.e., associate_integer_pointer must be called
     477              :    sometime later.  Returns the pointer_info structure.  */
     478              : 
     479              : static pointer_info *
     480      5211168 : add_fixup (HOST_WIDE_INT integer, void *gp)
     481              : {
     482      5211168 :   pointer_info *p;
     483      5211168 :   fixup_t *f;
     484      5211168 :   char **cp;
     485              : 
     486      5211168 :   p = get_integer (integer);
     487              : 
     488      5211168 :   if (p->integer == 0 || p->u.pointer != NULL)
     489              :     {
     490      4383712 :       cp = (char **) gp;
     491      4383712 :       *cp = (char *) p->u.pointer;
     492              :     }
     493              :   else
     494              :     {
     495       827456 :       f = XCNEW (fixup_t);
     496              : 
     497       827456 :       f->next = p->fixup;
     498       827456 :       p->fixup = f;
     499              : 
     500       827456 :       f->pointer = (void **) gp;
     501              :     }
     502              : 
     503      5211168 :   return p;
     504              : }
     505              : 
     506              : 
     507              : /*****************************************************************/
     508              : 
     509              : /* Parser related subroutines */
     510              : 
     511              : /* Free the rename list left behind by a USE statement.  */
     512              : 
     513              : static void
     514        90271 : free_rename (gfc_use_rename *list)
     515              : {
     516        90271 :   gfc_use_rename *next;
     517              : 
     518       100376 :   for (; list; list = next)
     519              :     {
     520        10105 :       next = list->next;
     521        10105 :       free (list);
     522              :     }
     523            0 : }
     524              : 
     525              : 
     526              : /* Match a USE statement.  */
     527              : 
     528              : match
     529        23169 : gfc_match_use (void)
     530              : {
     531        23169 :   char name[GFC_MAX_SYMBOL_LEN + 1], module_nature[GFC_MAX_SYMBOL_LEN + 1];
     532        23169 :   gfc_use_rename *tail = NULL, *new_use;
     533        23169 :   interface_type type, type2;
     534        23169 :   gfc_intrinsic_op op;
     535        23169 :   match m;
     536        23169 :   gfc_use_list *use_list;
     537        23169 :   gfc_symtree *st;
     538        23169 :   locus loc;
     539              : 
     540        23169 :   use_list = gfc_get_use_list ();
     541              : 
     542        23169 :   if (gfc_match (" , ") == MATCH_YES)
     543              :     {
     544         3435 :       if ((m = gfc_match (" %n ::", module_nature)) == MATCH_YES)
     545              :         {
     546         3433 :           if (!gfc_notify_std (GFC_STD_F2003, "module "
     547              :                                "nature in USE statement at %C"))
     548            0 :             goto cleanup;
     549              : 
     550         3433 :           if (strcmp (module_nature, "intrinsic") == 0)
     551         3419 :             use_list->intrinsic = true;
     552              :           else
     553              :             {
     554           14 :               if (strcmp (module_nature, "non_intrinsic") == 0)
     555           13 :                 use_list->non_intrinsic = true;
     556              :               else
     557              :                 {
     558            1 :                   gfc_error ("Module nature in USE statement at %C shall "
     559              :                              "be either INTRINSIC or NON_INTRINSIC");
     560            1 :                   goto cleanup;
     561              :                 }
     562              :             }
     563              :         }
     564              :       else
     565              :         {
     566              :           /* Help output a better error message than "Unclassifiable
     567              :              statement".  */
     568            2 :           gfc_match (" %n", module_nature);
     569            2 :           if (strcmp (module_nature, "intrinsic") == 0
     570            1 :               || strcmp (module_nature, "non_intrinsic") == 0)
     571            2 :             gfc_error ("\"::\" was expected after module nature at %C "
     572              :                        "but was not found");
     573            2 :           free (use_list);
     574            2 :           return m;
     575              :         }
     576              :     }
     577              :   else
     578              :     {
     579        19734 :       m = gfc_match (" ::");
     580        20066 :       if (m == MATCH_YES &&
     581          332 :           !gfc_notify_std(GFC_STD_F2003, "\"USE :: module\" at %C"))
     582            0 :         goto cleanup;
     583              : 
     584        19734 :       if (m != MATCH_YES)
     585              :         {
     586        19402 :           m = gfc_match ("% ");
     587        19402 :           if (m != MATCH_YES)
     588              :             {
     589           17 :               free (use_list);
     590           17 :               return m;
     591              :             }
     592              :         }
     593              :     }
     594              : 
     595        23149 :   use_list->where = gfc_current_locus;
     596              : 
     597        23149 :   m = gfc_match_name (name);
     598        23149 :   if (m != MATCH_YES)
     599              :     {
     600           12 :       free (use_list);
     601           12 :       return m;
     602              :     }
     603              : 
     604        23137 :   use_list->module_name = gfc_get_string ("%s", name);
     605              : 
     606        23137 :   if (gfc_match_eos () == MATCH_YES)
     607        14518 :     goto done;
     608              : 
     609         8619 :   if (gfc_match_char (',') != MATCH_YES)
     610            0 :     goto syntax;
     611              : 
     612         8619 :   if (gfc_match (" only :") == MATCH_YES)
     613         8376 :     use_list->only_flag = true;
     614              : 
     615         8619 :   if (gfc_match_eos () == MATCH_YES)
     616            1 :     goto done;
     617              : 
     618        13018 :   for (;;)
     619              :     {
     620              :       /* Get a new rename struct and add it to the rename list.  */
     621        13018 :       new_use = gfc_get_use_rename ();
     622        13018 :       new_use->where = gfc_current_locus;
     623        13018 :       new_use->found = 0;
     624              : 
     625        13018 :       if (use_list->rename == NULL)
     626         8618 :         use_list->rename = new_use;
     627              :       else
     628         4400 :         tail->next = new_use;
     629        13018 :       tail = new_use;
     630              : 
     631              :       /* See what kind of interface we're dealing with.  Assume it is
     632              :          not an operator.  */
     633        13018 :       new_use->op = INTRINSIC_NONE;
     634        13018 :       if (gfc_match_generic_spec (&type, name, &op) == MATCH_ERROR)
     635            0 :         goto cleanup;
     636              : 
     637        13018 :       switch (type)
     638              :         {
     639            1 :         case INTERFACE_NAMELESS:
     640            1 :           gfc_error ("Missing generic specification in USE statement at %C");
     641            1 :           goto cleanup;
     642              : 
     643        12900 :         case INTERFACE_USER_OP:
     644        12900 :         case INTERFACE_GENERIC:
     645        12900 :         case INTERFACE_DTIO:
     646        12900 :           loc = gfc_current_locus;
     647              : 
     648        12900 :           m = gfc_match (" =>");
     649              : 
     650           79 :           if (type == INTERFACE_USER_OP && m == MATCH_YES
     651        12946 :               && (!gfc_notify_std(GFC_STD_F2003, "Renaming "
     652              :                                   "operators in USE statements at %C")))
     653            2 :             goto cleanup;
     654              : 
     655        12898 :           if (type == INTERFACE_USER_OP)
     656           77 :             new_use->op = INTRINSIC_USER;
     657              : 
     658        12898 :           if (use_list->only_flag)
     659              :             {
     660        12552 :               if (m != MATCH_YES)
     661        12229 :                 strcpy (new_use->use_name, name);
     662              :               else
     663              :                 {
     664          323 :                   strcpy (new_use->local_name, name);
     665          323 :                   m = gfc_match_generic_spec (&type2, new_use->use_name, &op);
     666          323 :                   if (type != type2)
     667            1 :                     goto syntax;
     668          322 :                   if (m == MATCH_NO)
     669            0 :                     goto syntax;
     670          322 :                   if (m == MATCH_ERROR)
     671            0 :                     goto cleanup;
     672              :                 }
     673              :             }
     674              :           else
     675              :             {
     676          346 :               if (m != MATCH_YES)
     677            0 :                 goto syntax;
     678          346 :               strcpy (new_use->local_name, name);
     679              : 
     680          346 :               m = gfc_match_generic_spec (&type2, new_use->use_name, &op);
     681          346 :               if (type != type2)
     682            2 :                 goto syntax;
     683          344 :               if (m == MATCH_NO)
     684            0 :                 goto syntax;
     685          344 :               if (m == MATCH_ERROR)
     686            0 :                 goto cleanup;
     687              :             }
     688              : 
     689        12895 :           st = gfc_find_symtree (gfc_current_ns->sym_root, name);
     690        12895 :           if (st && type != INTERFACE_USER_OP
     691           13 :               && (st->n.sym->module != use_list->module_name
     692            3 :                   || strcmp (st->n.sym->name, new_use->use_name) != 0))
     693              :             {
     694           10 :               if (m == MATCH_YES)
     695            7 :                 gfc_error ("Symbol %qs at %L conflicts with the rename symbol "
     696              :                            "at %L", name, &st->n.sym->declared_at, &loc);
     697              :               else
     698            3 :                 gfc_error ("Symbol %qs at %L conflicts with the symbol "
     699              :                            "at %L", name, &st->n.sym->declared_at, &loc);
     700           10 :               goto cleanup;
     701              :             }
     702              : 
     703        12885 :           if (strcmp (new_use->use_name, use_list->module_name) == 0
     704        12883 :               || strcmp (new_use->local_name, use_list->module_name) == 0)
     705              :             {
     706            3 :               gfc_error ("The name %qs at %C has already been used as "
     707              :                          "an external module name", use_list->module_name);
     708            3 :               goto cleanup;
     709              :             }
     710              :           break;
     711              : 
     712          117 :         case INTERFACE_INTRINSIC_OP:
     713          117 :           new_use->op = op;
     714          117 :           break;
     715              : 
     716            0 :         default:
     717            0 :           gcc_unreachable ();
     718              :         }
     719              : 
     720        12999 :       if (gfc_match_eos () == MATCH_YES)
     721              :         break;
     722         4402 :       if (gfc_match_char (',') != MATCH_YES)
     723            2 :         goto syntax;
     724              :     }
     725              : 
     726         8597 : done:
     727        23116 :   if (module_list)
     728              :     {
     729              :       gfc_use_list *last = module_list;
     730         4137 :       while (last->next)
     731              :         last = last->next;
     732         3298 :       last->next = use_list;
     733              :     }
     734              :   else
     735        19818 :     module_list = use_list;
     736              : 
     737              :   return MATCH_YES;
     738              : 
     739            5 : syntax:
     740            5 :   gfc_syntax_error (ST_USE);
     741              : 
     742           22 : cleanup:
     743           22 :   free_rename (use_list->rename);
     744           22 :   free (use_list);
     745           22 :   return MATCH_ERROR;
     746              : }
     747              : 
     748              : 
     749              : /* Match a SUBMODULE statement.
     750              : 
     751              :    According to F2008:11.2.3.2, "The submodule identifier is the
     752              :    ordered pair whose first element is the ancestor module name and
     753              :    whose second element is the submodule name. 'Submodule_name' is
     754              :    used for the submodule filename and uses '@' as a separator, whilst
     755              :    the name of the symbol for the module uses '.' as a separator.
     756              :    The reasons for these choices are:
     757              :    (i) To follow another leading brand in the submodule filenames;
     758              :    (ii) Since '.' is not particularly visible in the filenames; and
     759              :    (iii) The linker does not permit '@' in mnemonics.  */
     760              : 
     761              : match
     762          234 : gfc_match_submodule (void)
     763              : {
     764          234 :   match m;
     765          234 :   char name[GFC_MAX_SYMBOL_LEN + 1];
     766          234 :   gfc_use_list *use_list;
     767          234 :   bool seen_colon = false;
     768              : 
     769          234 :   if (!gfc_notify_std (GFC_STD_F2008, "SUBMODULE declaration at %C"))
     770              :     return MATCH_ERROR;
     771              : 
     772          233 :   if (gfc_current_state () != COMP_NONE)
     773              :     {
     774            3 :       gfc_error ("SUBMODULE declaration at %C cannot appear within "
     775              :                  "another scoping unit");
     776            3 :       return MATCH_ERROR;
     777              :     }
     778              : 
     779          230 :   gfc_new_block = NULL;
     780          230 :   gcc_assert (module_list == NULL);
     781              : 
     782          230 :   if (gfc_match_char ('(') != MATCH_YES)
     783            0 :     goto syntax;
     784              : 
     785          256 :   while (1)
     786              :     {
     787          256 :       m = gfc_match (" %n", name);
     788          256 :       if (m != MATCH_YES)
     789            0 :         goto syntax;
     790              : 
     791          256 :       use_list = gfc_get_use_list ();
     792          256 :       use_list->where = gfc_current_locus;
     793              : 
     794          256 :       if (module_list)
     795              :         {
     796              :           gfc_use_list *last = module_list;
     797           26 :           while (last->next)
     798              :             last = last->next;
     799           26 :           last->next = use_list;
     800           26 :           use_list->module_name
     801           26 :                 = gfc_get_string ("%s.%s", module_list->module_name, name);
     802           26 :           use_list->submodule_name
     803           26 :                 = gfc_get_string ("%s@%s", module_list->module_name, name);
     804              :         }
     805              :       else
     806              :         {
     807          230 :           module_list = use_list;
     808          230 :           use_list->module_name = gfc_get_string ("%s", name);
     809          230 :           use_list->submodule_name = use_list->module_name;
     810              :         }
     811              : 
     812          256 :       if (gfc_match_char (')') == MATCH_YES)
     813              :         break;
     814              : 
     815           54 :       if (gfc_match_char (':') != MATCH_YES
     816           27 :           || seen_colon)
     817            1 :         goto syntax;
     818              : 
     819              :       seen_colon = true;
     820              :     }
     821              : 
     822          229 :   m = gfc_match (" %s%t", &gfc_new_block);
     823          229 :   if (m != MATCH_YES)
     824            0 :     goto syntax;
     825              : 
     826          229 :   submodule_name = gfc_get_string ("%s@%s", module_list->module_name,
     827              :                                    gfc_new_block->name);
     828              : 
     829          229 :   gfc_new_block->name = gfc_get_string ("%s.%s",
     830              :                                         module_list->module_name,
     831              :                                         gfc_new_block->name);
     832              : 
     833          229 :   if (!gfc_add_flavor (&gfc_new_block->attr, FL_MODULE,
     834              :                        gfc_new_block->name, NULL))
     835              :     return MATCH_ERROR;
     836              : 
     837              :   /* Just retain the ultimate .(s)mod file for reading, since it
     838              :      contains all the information in its ancestors.  */
     839          229 :   use_list = module_list;
     840          254 :   for (; module_list->next; use_list = module_list)
     841              :     {
     842           25 :       module_list = use_list->next;
     843           25 :       free (use_list);
     844              :     }
     845              : 
     846              :   return MATCH_YES;
     847              : 
     848            1 : syntax:
     849            1 :   gfc_error ("Syntax error in SUBMODULE statement at %C");
     850            1 :   return MATCH_ERROR;
     851              : }
     852              : 
     853              : 
     854              : /* Given a name and a number, inst, return the inst name
     855              :    under which to load this symbol. Returns NULL if this
     856              :    symbol shouldn't be loaded. If inst is zero, returns
     857              :    the number of instances of this name. If interface is
     858              :    true, a user-defined operator is sought, otherwise only
     859              :    non-operators are sought.  */
     860              : 
     861              : static const char *
     862      1086757 : find_use_name_n (const char *name, int *inst, bool interface)
     863              : {
     864      1086757 :   gfc_use_rename *u;
     865      1086757 :   const char *low_name = NULL;
     866      1086757 :   int i;
     867              : 
     868              :   /* For derived types.  */
     869      1086757 :   if (name[0] != (char) TOLOWER ((unsigned char) name[0]))
     870        28306 :     low_name = gfc_dt_lower_string (name);
     871              : 
     872      1086757 :   i = 0;
     873      1228131 :   for (u = gfc_rename_list; u; u = u->next)
     874              :     {
     875       145588 :       if ((!low_name && strcmp (u->use_name, name) != 0)
     876         3470 :           || (low_name && strcmp (u->use_name, low_name) != 0)
     877         8469 :           || (u->op == INTRINSIC_USER && !interface)
     878         8467 :           || (u->op != INTRINSIC_USER &&  interface))
     879       137121 :         continue;
     880         8467 :       if (++i == *inst)
     881              :         break;
     882              :     }
     883              : 
     884      1086757 :   if (!*inst)
     885              :     {
     886       543307 :       *inst = i;
     887       543307 :       return NULL;
     888              :     }
     889              : 
     890       543450 :   if (u == NULL)
     891       593870 :     return only_flag ? NULL : name;
     892              : 
     893         4214 :   u->found = 1;
     894              : 
     895         4214 :   if (low_name)
     896              :     {
     897          691 :       if (u->local_name[0] == '\0')
     898              :         return name;
     899          100 :       return gfc_dt_upper_string (u->local_name);
     900              :     }
     901              : 
     902         3523 :   return (u->local_name[0] != '\0') ? u->local_name : name;
     903              : }
     904              : 
     905              : 
     906              : /* Given a name, return the name under which to load this symbol.
     907              :    Returns NULL if this symbol shouldn't be loaded.  */
     908              : 
     909              : static const char *
     910           86 : find_use_name (const char *name, bool interface)
     911              : {
     912           86 :   int i = 1;
     913           50 :   return find_use_name_n (name, &i, interface);
     914              : }
     915              : 
     916              : 
     917              : /* Given a real name, return the number of use names associated with it.  */
     918              : 
     919              : static int
     920       543307 : number_use_names (const char *name, bool interface)
     921              : {
     922       543307 :   int i = 0;
     923            0 :   find_use_name_n (name, &i, interface);
     924       543307 :   return i;
     925              : }
     926              : 
     927              : 
     928              : /* Try to find the operator in the current list.  */
     929              : 
     930              : static gfc_use_rename *
     931        69348 : find_use_operator (gfc_intrinsic_op op)
     932              : {
     933        69348 :   gfc_use_rename *u;
     934              : 
     935       170457 :   for (u = gfc_rename_list; u; u = u->next)
     936       101317 :     if (u->op == op)
     937              :       return u;
     938              : 
     939              :   return NULL;
     940              : }
     941              : 
     942              : 
     943              : /*****************************************************************/
     944              : 
     945              : /* The next couple of subroutines maintain a tree used to avoid a
     946              :    brute-force search for a combination of true name and module name.
     947              :    While symtree names, the name that a particular symbol is known by
     948              :    can changed with USE statements, we still have to keep track of the
     949              :    true names to generate the correct reference, and also avoid
     950              :    loading the same real symbol twice in a program unit.
     951              : 
     952              :    When we start reading, the true name tree is built and maintained
     953              :    as symbols are read.  The tree is searched as we load new symbols
     954              :    to see if it already exists someplace in the namespace.  */
     955              : 
     956              : typedef struct true_name
     957              : {
     958              :   BBT_HEADER (true_name);
     959              :   const char *name;
     960              :   gfc_symbol *sym;
     961              : }
     962              : true_name;
     963              : 
     964              : static true_name *true_name_root;
     965              : 
     966              : 
     967              : /* Compare two true_name structures.  */
     968              : 
     969              : static int
     970      3276434 : compare_true_names (void *_t1, void *_t2)
     971              : {
     972      3276434 :   true_name *t1, *t2;
     973      3276434 :   int c;
     974              : 
     975      3276434 :   t1 = (true_name *) _t1;
     976      3276434 :   t2 = (true_name *) _t2;
     977              : 
     978      3276434 :   c = ((t1->sym->module > t2->sym->module)
     979      3276434 :        - (t1->sym->module < t2->sym->module));
     980      3276434 :   if (c != 0)
     981              :     return c;
     982              : 
     983       994034 :   return strcmp (t1->name, t2->name);
     984              : }
     985              : 
     986              : 
     987              : /* Given a true name, search the true name tree to see if it exists
     988              :    within the main namespace.  */
     989              : 
     990              : static gfc_symbol *
     991      1295938 : find_true_name (const char *name, const char *module)
     992              : {
     993      1295938 :   true_name t, *p;
     994      1295938 :   gfc_symbol sym;
     995      1295938 :   int c;
     996              : 
     997      1295938 :   t.name = gfc_get_string ("%s", name);
     998      1295938 :   if (module != NULL)
     999      1275207 :     sym.module = gfc_get_string ("%s", module);
    1000              :   else
    1001        20731 :     sym.module = NULL;
    1002      1295938 :   t.sym = &sym;
    1003              : 
    1004      1295938 :   p = true_name_root;
    1005      4122130 :   while (p != NULL)
    1006              :     {
    1007      2875690 :       c = compare_true_names ((void *) (&t), (void *) p);
    1008      2875690 :       if (c == 0)
    1009        49498 :         return p->sym;
    1010              : 
    1011      2826192 :       p = (c < 0) ? p->left : p->right;
    1012              :     }
    1013              : 
    1014              :   return NULL;
    1015              : }
    1016              : 
    1017              : 
    1018              : /* Given a gfc_symbol pointer that is not in the true name tree, add it.  */
    1019              : 
    1020              : static void
    1021       101120 : add_true_name (gfc_symbol *sym)
    1022              : {
    1023       101120 :   true_name *t;
    1024              : 
    1025       101120 :   t = XCNEW (true_name);
    1026       101120 :   t->sym = sym;
    1027       101120 :   if (gfc_fl_struct (sym->attr.flavor))
    1028         5696 :     t->name = gfc_dt_upper_string (sym->name);
    1029              :   else
    1030        95424 :     t->name = sym->name;
    1031              : 
    1032       101120 :   gfc_insert_bbt (&true_name_root, t, compare_true_names);
    1033       101120 : }
    1034              : 
    1035              : 
    1036              : /* Recursive function to build the initial true name tree by
    1037              :    recursively traversing the current namespace.  */
    1038              : 
    1039              : static void
    1040       217061 : build_tnt (gfc_symtree *st)
    1041              : {
    1042       217061 :   const char *name;
    1043       217061 :   if (st == NULL)
    1044              :     return;
    1045              : 
    1046       101889 :   build_tnt (st->left);
    1047       101889 :   build_tnt (st->right);
    1048              : 
    1049       101889 :   if (gfc_fl_struct (st->n.sym->attr.flavor))
    1050         6138 :     name = gfc_dt_upper_string (st->n.sym->name);
    1051              :   else
    1052        95751 :     name = st->n.sym->name;
    1053              : 
    1054       101889 :   if (find_true_name (name, st->n.sym->module) != NULL)
    1055              :     return;
    1056              : 
    1057       101120 :   add_true_name (st->n.sym);
    1058              : }
    1059              : 
    1060              : 
    1061              : /* Initialize the true name tree with the current namespace.  */
    1062              : 
    1063              : static void
    1064        13283 : init_true_name_tree (void)
    1065              : {
    1066        13283 :   true_name_root = NULL;
    1067        13283 :   build_tnt (gfc_current_ns->sym_root);
    1068        13283 : }
    1069              : 
    1070              : 
    1071              : /* Recursively free a true name tree node.  */
    1072              : 
    1073              : static void
    1074       215523 : free_true_name (true_name *t)
    1075              : {
    1076       215523 :   if (t == NULL)
    1077              :     return;
    1078       101120 :   free_true_name (t->left);
    1079       101120 :   free_true_name (t->right);
    1080              : 
    1081       101120 :   free (t);
    1082              : }
    1083              : 
    1084              : 
    1085              : /*****************************************************************/
    1086              : 
    1087              : /* Module reading and writing.  */
    1088              : 
    1089              : /* The following are versions similar to the ones in scanner.cc, but
    1090              :    for dealing with compressed module files.  */
    1091              : 
    1092              : static gzFile
    1093         9891 : gzopen_included_file_1 (const char *name, gfc_directorylist *list,
    1094              :                      bool module, bool system)
    1095              : {
    1096         9891 :   char *fullname;
    1097         9891 :   gfc_directorylist *p;
    1098         9891 :   gzFile f;
    1099              : 
    1100        34495 :   for (p = list; p; p = p->next)
    1101              :     {
    1102        26771 :       if (module && !p->use_for_modules)
    1103         4205 :        continue;
    1104              : 
    1105        22566 :       fullname = (char *) alloca(strlen (p->path) + strlen (name) + 2);
    1106        22566 :       strcpy (fullname, p->path);
    1107        22566 :       strcat (fullname, "/");
    1108        22566 :       strcat (fullname, name);
    1109              : 
    1110        22566 :       f = gzopen (fullname, "r");
    1111        22566 :       if (f != NULL)
    1112              :        {
    1113         2167 :          if (gfc_cpp_makedep ())
    1114            0 :            gfc_cpp_add_dep (fullname, system);
    1115              : 
    1116         2167 :          free (module_fullpath);
    1117         2167 :          module_fullpath = xstrdup (fullname);
    1118         2167 :          return f;
    1119              :        }
    1120              :     }
    1121              : 
    1122              :   return NULL;
    1123              : }
    1124              : 
    1125              : static gzFile
    1126        19791 : gzopen_included_file (const char *name, bool include_cwd, bool module)
    1127              : {
    1128        19791 :   gzFile f = NULL;
    1129              : 
    1130        19791 :   if (IS_ABSOLUTE_PATH (name) || include_cwd)
    1131              :     {
    1132        19791 :       f = gzopen (name, "r");
    1133        19791 :       if (f)
    1134              :         {
    1135        11116 :           if (gfc_cpp_makedep ())
    1136            0 :             gfc_cpp_add_dep (name, false);
    1137              : 
    1138        11116 :           free (module_fullpath);
    1139        11116 :           module_fullpath = xstrdup (name);
    1140              :         }
    1141              :     }
    1142              : 
    1143        11116 :   if (!f)
    1144         8675 :     f = gzopen_included_file_1 (name, include_dirs, module, false);
    1145              : 
    1146        19791 :   return f;
    1147              : }
    1148              : 
    1149              : static gzFile
    1150         1216 : gzopen_intrinsic_module (const char* name)
    1151              : {
    1152         1216 :   gzFile f = NULL;
    1153              : 
    1154         1216 :   if (IS_ABSOLUTE_PATH (name))
    1155              :     {
    1156            0 :       f = gzopen (name, "r");
    1157            0 :       if (f)
    1158              :         {
    1159            0 :           if (gfc_cpp_makedep ())
    1160            0 :             gfc_cpp_add_dep (name, true);
    1161              : 
    1162            0 :           free (module_fullpath);
    1163            0 :           module_fullpath = xstrdup (name);
    1164              :         }
    1165              :     }
    1166              : 
    1167            0 :   if (!f)
    1168         1216 :     f = gzopen_included_file_1 (name, intrinsic_modules_dirs, true, true);
    1169              : 
    1170         1216 :   return f;
    1171              : }
    1172              : 
    1173              : 
    1174              : enum atom_type
    1175              : {
    1176              :   ATOM_NAME, ATOM_LPAREN, ATOM_RPAREN, ATOM_INTEGER, ATOM_STRING
    1177              : };
    1178              : 
    1179              : static atom_type last_atom;
    1180              : 
    1181              : 
    1182              : /* The name buffer must be at least as long as a symbol name.  Right
    1183              :    now it's not clear how we're going to store numeric constants--
    1184              :    probably as a hexadecimal string, since this will allow the exact
    1185              :    number to be preserved (this can't be done by a decimal
    1186              :    representation).  Worry about that later.  TODO!  */
    1187              : 
    1188              : #define MAX_ATOM_SIZE 100
    1189              : 
    1190              : static HOST_WIDE_INT atom_int;
    1191              : static char *atom_string, atom_name[MAX_ATOM_SIZE];
    1192              : 
    1193              : 
    1194              : /* Report problems with a module.  Error reporting is not very
    1195              :    elaborate, since this sorts of errors shouldn't really happen.
    1196              :    This subroutine never returns.  */
    1197              : 
    1198              : static void bad_module (const char *) ATTRIBUTE_NORETURN;
    1199              : 
    1200              : static void
    1201            0 : bad_module (const char *msgid)
    1202              : {
    1203            0 :   XDELETEVEC (module_content);
    1204            0 :   module_content = NULL;
    1205              : 
    1206            0 :   switch (iomode)
    1207              :     {
    1208            0 :     case IO_INPUT:
    1209            0 :       gfc_fatal_error ("Reading module %qs at line %d column %d: %s",
    1210              :                        module_fullpath, module_line, module_column, msgid);
    1211            0 :       break;
    1212            0 :     case IO_OUTPUT:
    1213            0 :       gfc_fatal_error ("Writing module %qs at line %d column %d: %s",
    1214              :                        module_name, module_line, module_column, msgid);
    1215            0 :       break;
    1216            0 :     default:
    1217            0 :       gfc_fatal_error ("Module %qs at line %d column %d: %s",
    1218              :                        module_name, module_line, module_column, msgid);
    1219              :       break;
    1220              :     }
    1221              : }
    1222              : 
    1223              : 
    1224              : /* Set the module's input pointer.  */
    1225              : 
    1226              : static void
    1227      1033354 : set_module_locus (module_locus *m)
    1228              : {
    1229      1033354 :   module_column = m->column;
    1230      1033354 :   module_line = m->line;
    1231      1033354 :   module_pos = m->pos;
    1232            0 : }
    1233              : 
    1234              : 
    1235              : /* Get the module's input pointer so that we can restore it later.  */
    1236              : 
    1237              : static void
    1238      1233918 : get_module_locus (module_locus *m)
    1239              : {
    1240      1233918 :   m->column = module_column;
    1241      1233918 :   m->line = module_line;
    1242      1233918 :   m->pos = module_pos;
    1243            0 : }
    1244              : 
    1245              : /* Peek at the next character in the module.  */
    1246              : 
    1247              : static int
    1248          532 : module_peek_char (void)
    1249              : {
    1250          532 :   return module_content[module_pos];
    1251              : }
    1252              : 
    1253              : /* Get the next character in the module, updating our reckoning of
    1254              :    where we are.  */
    1255              : 
    1256              : static int
    1257    529942948 : module_char (void)
    1258              : {
    1259    529942948 :   const char c = module_content[module_pos++];
    1260    529942948 :   if (c == '\0')
    1261            0 :     bad_module ("Unexpected EOF");
    1262              : 
    1263    529942948 :   prev_module_line = module_line;
    1264    529942948 :   prev_module_column = module_column;
    1265              : 
    1266    529942948 :   if (c == '\n')
    1267              :     {
    1268     11305317 :       module_line++;
    1269     11305317 :       module_column = 0;
    1270              :     }
    1271              : 
    1272    529942948 :   module_column++;
    1273    529942948 :   return c;
    1274              : }
    1275              : 
    1276              : /* Unget a character while remembering the line and column.  Works for
    1277              :    a single character only.  */
    1278              : 
    1279              : static void
    1280     78270541 : module_unget_char (void)
    1281              : {
    1282     78270541 :   module_line = prev_module_line;
    1283     78270541 :   module_column = prev_module_column;
    1284     78270541 :   module_pos--;
    1285            0 : }
    1286              : 
    1287              : /* Parse a string constant.  The delimiter is guaranteed to be a
    1288              :    single quote.  */
    1289              : 
    1290              : static void
    1291      5384333 : parse_string (void)
    1292              : {
    1293      5384333 :   int c;
    1294      5384333 :   size_t cursz = 30;
    1295      5384333 :   size_t len = 0;
    1296              : 
    1297      5384333 :   atom_string = XNEWVEC (char, cursz);
    1298              : 
    1299     80153735 :   for ( ; ; )
    1300              :     {
    1301     42769034 :       c = module_char ();
    1302              : 
    1303     42769034 :       if (c == '\'')
    1304              :         {
    1305      5384333 :           int c2 = module_char ();
    1306      5384333 :           if (c2 != '\'')
    1307              :             {
    1308      5384333 :               module_unget_char ();
    1309      5384333 :               break;
    1310              :             }
    1311              :         }
    1312              : 
    1313     37384701 :       if (len >= cursz)
    1314              :         {
    1315        59220 :           cursz *= 2;
    1316        59220 :           atom_string = XRESIZEVEC (char, atom_string, cursz);
    1317              :         }
    1318     37384701 :       atom_string[len] = c;
    1319     37384701 :       len++;
    1320     37384701 :     }
    1321              : 
    1322      5384333 :   atom_string = XRESIZEVEC (char, atom_string, len + 1);
    1323      5384333 :   atom_string[len] = '\0';      /* C-style string for debug purposes.  */
    1324      5384333 : }
    1325              : 
    1326              : 
    1327              : /* Parse an integer. Should fit in a HOST_WIDE_INT.  */
    1328              : 
    1329              : static void
    1330     34987100 : parse_integer (int c)
    1331              : {
    1332     34987100 :   int sign = 1;
    1333              : 
    1334     34987100 :   atom_int = 0;
    1335     34987100 :   switch (c)
    1336              :     {
    1337              :     case ('-'):
    1338     34987100 :       sign = -1;
    1339              :     case ('+'):
    1340              :       break;
    1341     34986568 :     default:
    1342     34986568 :       atom_int = c - '0';
    1343     34986568 :       break;
    1344              :     }
    1345              : 
    1346     52360020 :   for (;;)
    1347              :     {
    1348     43673560 :       c = module_char ();
    1349     43673560 :       if (!ISDIGIT (c))
    1350              :         {
    1351     34987100 :           module_unget_char ();
    1352     34987100 :           break;
    1353              :         }
    1354              : 
    1355      8686460 :       atom_int = 10 * atom_int + c - '0';
    1356              :     }
    1357              : 
    1358     34987100 :   atom_int *= sign;
    1359     34987100 : }
    1360              : 
    1361              : 
    1362              : /* Parse a name.  */
    1363              : 
    1364              : static void
    1365     25521924 : parse_name (int c)
    1366              : {
    1367     25521924 :   char *p;
    1368     25521924 :   int len;
    1369              : 
    1370     25521924 :   p = atom_name;
    1371              : 
    1372     25521924 :   *p++ = c;
    1373     25521924 :   len = 1;
    1374              : 
    1375    217240462 :   for (;;)
    1376              :     {
    1377    217240462 :       c = module_char ();
    1378    217240462 :       if (!ISALNUM (c) && c != '_' && c != '-')
    1379              :         {
    1380     25521924 :           module_unget_char ();
    1381     25521924 :           break;
    1382              :         }
    1383              : 
    1384    191718538 :       *p++ = c;
    1385    191718538 :       if (++len > GFC_MAX_SYMBOL_LEN)
    1386            0 :         bad_module ("Name too long");
    1387              :     }
    1388              : 
    1389     25521924 :   *p = '\0';
    1390              : 
    1391     25521924 : }
    1392              : 
    1393              : 
    1394              : /* Read the next atom in the module's input stream.  */
    1395              : 
    1396              : static atom_type
    1397    123156238 : parse_atom (void)
    1398              : {
    1399    205805049 :   int c;
    1400              : 
    1401    205805049 :   do
    1402              :     {
    1403    205805049 :       c = module_char ();
    1404              :     }
    1405    205805049 :   while (c == ' ' || c == '\r' || c == '\n');
    1406              : 
    1407    123156238 :   switch (c)
    1408              :     {
    1409              :     case '(':
    1410              :       return ATOM_LPAREN;
    1411              : 
    1412     28651355 :     case ')':
    1413     28651355 :       return ATOM_RPAREN;
    1414              : 
    1415      5384333 :     case '\'':
    1416      5384333 :       parse_string ();
    1417      5384333 :       return ATOM_STRING;
    1418              : 
    1419     34986568 :     case '0':
    1420     34986568 :     case '1':
    1421     34986568 :     case '2':
    1422     34986568 :     case '3':
    1423     34986568 :     case '4':
    1424     34986568 :     case '5':
    1425     34986568 :     case '6':
    1426     34986568 :     case '7':
    1427     34986568 :     case '8':
    1428     34986568 :     case '9':
    1429     34986568 :       parse_integer (c);
    1430     34986568 :       return ATOM_INTEGER;
    1431              : 
    1432          532 :     case '+':
    1433          532 :     case '-':
    1434          532 :       if (ISDIGIT (module_peek_char ()))
    1435              :         {
    1436          532 :           parse_integer (c);
    1437          532 :           return ATOM_INTEGER;
    1438              :         }
    1439              :       else
    1440            0 :         bad_module ("Bad name");
    1441              : 
    1442     25482075 :     case 'a':
    1443     25482075 :     case 'b':
    1444     25482075 :     case 'c':
    1445     25482075 :     case 'd':
    1446     25482075 :     case 'e':
    1447     25482075 :     case 'f':
    1448     25482075 :     case 'g':
    1449     25482075 :     case 'h':
    1450     25482075 :     case 'i':
    1451     25482075 :     case 'j':
    1452     25482075 :     case 'k':
    1453     25482075 :     case 'l':
    1454     25482075 :     case 'm':
    1455     25482075 :     case 'n':
    1456     25482075 :     case 'o':
    1457     25482075 :     case 'p':
    1458     25482075 :     case 'q':
    1459     25482075 :     case 'r':
    1460     25482075 :     case 's':
    1461     25482075 :     case 't':
    1462     25482075 :     case 'u':
    1463     25482075 :     case 'v':
    1464     25482075 :     case 'w':
    1465     25482075 :     case 'x':
    1466     25482075 :     case 'y':
    1467     25482075 :     case 'z':
    1468     25482075 :     case 'A':
    1469     25482075 :     case 'B':
    1470     25482075 :     case 'C':
    1471     25482075 :     case 'D':
    1472     25482075 :     case 'E':
    1473     25482075 :     case 'F':
    1474     25482075 :     case 'G':
    1475     25482075 :     case 'H':
    1476     25482075 :     case 'I':
    1477     25482075 :     case 'J':
    1478     25482075 :     case 'K':
    1479     25482075 :     case 'L':
    1480     25482075 :     case 'M':
    1481     25482075 :     case 'N':
    1482     25482075 :     case 'O':
    1483     25482075 :     case 'P':
    1484     25482075 :     case 'Q':
    1485     25482075 :     case 'R':
    1486     25482075 :     case 'S':
    1487     25482075 :     case 'T':
    1488     25482075 :     case 'U':
    1489     25482075 :     case 'V':
    1490     25482075 :     case 'W':
    1491     25482075 :     case 'X':
    1492     25482075 :     case 'Y':
    1493     25482075 :     case 'Z':
    1494     25482075 :       parse_name (c);
    1495     25482075 :       return ATOM_NAME;
    1496              : 
    1497            0 :     default:
    1498            0 :       bad_module ("Bad name");
    1499              :     }
    1500              : 
    1501              :   /* Not reached.  */
    1502              : }
    1503              : 
    1504              : 
    1505              : /* Peek at the next atom on the input.  */
    1506              : 
    1507              : static atom_type
    1508     12377184 : peek_atom (void)
    1509              : {
    1510     14593435 :   int c;
    1511              : 
    1512     14593435 :   do
    1513              :     {
    1514     14593435 :       c = module_char ();
    1515              :     }
    1516     14593435 :   while (c == ' ' || c == '\r' || c == '\n');
    1517              : 
    1518     12377184 :   switch (c)
    1519              :     {
    1520       284573 :     case '(':
    1521       284573 :       module_unget_char ();
    1522       284573 :       return ATOM_LPAREN;
    1523              : 
    1524      9769682 :     case ')':
    1525      9769682 :       module_unget_char ();
    1526      9769682 :       return ATOM_RPAREN;
    1527              : 
    1528       489432 :     case '\'':
    1529       489432 :       module_unget_char ();
    1530       489432 :       return ATOM_STRING;
    1531              : 
    1532      1828488 :     case '0':
    1533      1828488 :     case '1':
    1534      1828488 :     case '2':
    1535      1828488 :     case '3':
    1536      1828488 :     case '4':
    1537      1828488 :     case '5':
    1538      1828488 :     case '6':
    1539      1828488 :     case '7':
    1540      1828488 :     case '8':
    1541      1828488 :     case '9':
    1542      1828488 :       module_unget_char ();
    1543      1828488 :       return ATOM_INTEGER;
    1544              : 
    1545            0 :     case '+':
    1546            0 :     case '-':
    1547            0 :       if (ISDIGIT (module_peek_char ()))
    1548              :         {
    1549            0 :           module_unget_char ();
    1550            0 :           return ATOM_INTEGER;
    1551              :         }
    1552              :       else
    1553            0 :         bad_module ("Bad name");
    1554              : 
    1555         5009 :     case 'a':
    1556         5009 :     case 'b':
    1557         5009 :     case 'c':
    1558         5009 :     case 'd':
    1559         5009 :     case 'e':
    1560         5009 :     case 'f':
    1561         5009 :     case 'g':
    1562         5009 :     case 'h':
    1563         5009 :     case 'i':
    1564         5009 :     case 'j':
    1565         5009 :     case 'k':
    1566         5009 :     case 'l':
    1567         5009 :     case 'm':
    1568         5009 :     case 'n':
    1569         5009 :     case 'o':
    1570         5009 :     case 'p':
    1571         5009 :     case 'q':
    1572         5009 :     case 'r':
    1573         5009 :     case 's':
    1574         5009 :     case 't':
    1575         5009 :     case 'u':
    1576         5009 :     case 'v':
    1577         5009 :     case 'w':
    1578         5009 :     case 'x':
    1579         5009 :     case 'y':
    1580         5009 :     case 'z':
    1581         5009 :     case 'A':
    1582         5009 :     case 'B':
    1583         5009 :     case 'C':
    1584         5009 :     case 'D':
    1585         5009 :     case 'E':
    1586         5009 :     case 'F':
    1587         5009 :     case 'G':
    1588         5009 :     case 'H':
    1589         5009 :     case 'I':
    1590         5009 :     case 'J':
    1591         5009 :     case 'K':
    1592         5009 :     case 'L':
    1593         5009 :     case 'M':
    1594         5009 :     case 'N':
    1595         5009 :     case 'O':
    1596         5009 :     case 'P':
    1597         5009 :     case 'Q':
    1598         5009 :     case 'R':
    1599         5009 :     case 'S':
    1600         5009 :     case 'T':
    1601         5009 :     case 'U':
    1602         5009 :     case 'V':
    1603         5009 :     case 'W':
    1604         5009 :     case 'X':
    1605         5009 :     case 'Y':
    1606         5009 :     case 'Z':
    1607         5009 :       module_unget_char ();
    1608         5009 :       return ATOM_NAME;
    1609              : 
    1610            0 :     default:
    1611            0 :       bad_module ("Bad name");
    1612              :     }
    1613              : }
    1614              : 
    1615              : 
    1616              : /* Read the next atom from the input, requiring that it be a
    1617              :    particular kind.  */
    1618              : 
    1619              : static void
    1620     56148632 : require_atom (atom_type type)
    1621              : {
    1622     56148632 :   atom_type t;
    1623     56148632 :   const char *p;
    1624     56148632 :   int column, line;
    1625              : 
    1626     56148632 :   column = module_column;
    1627     56148632 :   line = module_line;
    1628              : 
    1629     56148632 :   t = parse_atom ();
    1630     56148632 :   if (t != type)
    1631              :     {
    1632            0 :       switch (type)
    1633              :         {
    1634            0 :         case ATOM_NAME:
    1635            0 :           p = _("Expected name");
    1636            0 :           break;
    1637            0 :         case ATOM_LPAREN:
    1638            0 :           p = _("Expected left parenthesis");
    1639            0 :           break;
    1640            0 :         case ATOM_RPAREN:
    1641            0 :           p = _("Expected right parenthesis");
    1642            0 :           break;
    1643            0 :         case ATOM_INTEGER:
    1644            0 :           p = _("Expected integer");
    1645            0 :           break;
    1646            0 :         case ATOM_STRING:
    1647            0 :           p = _("Expected string");
    1648            0 :           break;
    1649            0 :         default:
    1650            0 :           gfc_internal_error ("require_atom(): bad atom type required");
    1651              :         }
    1652              : 
    1653            0 :       module_column = column;
    1654            0 :       module_line = line;
    1655            0 :       bad_module (p);
    1656              :     }
    1657     56148632 : }
    1658              : 
    1659              : 
    1660              : /* Given a pointer to an mstring array, require that the current input
    1661              :    be one of the strings in the array.  We return the enum value.  */
    1662              : 
    1663              : static int
    1664     11617573 : find_enum (const mstring *m)
    1665              : {
    1666     11617573 :   int i;
    1667              : 
    1668     11617573 :   i = gfc_string2code (m, atom_name);
    1669     11617573 :   if (i >= 0)
    1670     11617573 :     return i;
    1671              : 
    1672            0 :   bad_module ("find_enum(): Enum not found");
    1673              : 
    1674              :   /* Not reached.  */
    1675              : }
    1676              : 
    1677              : 
    1678              : /* Read a string. The caller is responsible for freeing.  */
    1679              : 
    1680              : static char*
    1681      3582355 : read_string (void)
    1682              : {
    1683      3582355 :   char* p;
    1684            0 :   require_atom (ATOM_STRING);
    1685      3582355 :   p = atom_string;
    1686      3582355 :   atom_string = NULL;
    1687      3582355 :   return p;
    1688              : }
    1689              : 
    1690              : 
    1691              : /**************** Module output subroutines ***************************/
    1692              : 
    1693              : /* Output a character to a module file.  */
    1694              : 
    1695              : static void
    1696     65093926 : write_char (char out)
    1697              : {
    1698     65093926 :   if (gzputc (module_fp, out) == EOF)
    1699            0 :     gfc_fatal_error ("Error writing modules file: %s", xstrerror (errno));
    1700              : 
    1701     65093926 :   if (out != '\n')
    1702     63907233 :     module_column++;
    1703              :   else
    1704              :     {
    1705      1186693 :       module_column = 1;
    1706      1186693 :       module_line++;
    1707              :     }
    1708     65093926 : }
    1709              : 
    1710              : 
    1711              : /* Write an atom to a module.  The line wrapping isn't perfect, but it
    1712              :    should work most of the time.  This isn't that big of a deal, since
    1713              :    the file really isn't meant to be read by people anyway.  */
    1714              : 
    1715              : static void
    1716     17321816 : write_atom (atom_type atom, const void *v)
    1717              : {
    1718     17321816 :   char buffer[32];
    1719              : 
    1720              :   /* Workaround -Wmaybe-uninitialized false positive during
    1721              :      profiledbootstrap by initializing them.  */
    1722     17321816 :   int len;
    1723     17321816 :   HOST_WIDE_INT i = 0;
    1724     17321816 :   const char *p;
    1725              : 
    1726     17321816 :   switch (atom)
    1727              :     {
    1728              :     case ATOM_STRING:
    1729              :     case ATOM_NAME:
    1730              :       p = (const char *) v;
    1731              :       break;
    1732              : 
    1733              :     case ATOM_LPAREN:
    1734              :       p = "(";
    1735              :       break;
    1736              : 
    1737              :     case ATOM_RPAREN:
    1738              :       p = ")";
    1739              :       break;
    1740              : 
    1741      4707296 :     case ATOM_INTEGER:
    1742      4707296 :       i = *((const HOST_WIDE_INT *) v);
    1743              : 
    1744      4707296 :       snprintf (buffer, sizeof (buffer), HOST_WIDE_INT_PRINT_DEC, i);
    1745      4707296 :       p = buffer;
    1746      4707296 :       break;
    1747              : 
    1748            0 :     default:
    1749            0 :       gfc_internal_error ("write_atom(): Trying to write dab atom");
    1750              : 
    1751              :     }
    1752              : 
    1753     17321816 :   if(p == NULL || *p == '\0')
    1754              :      len = 0;
    1755              :   else
    1756     16960703 :   len = strlen (p);
    1757              : 
    1758     17321816 :   if (atom != ATOM_RPAREN)
    1759              :     {
    1760     13348930 :       if (module_column + len > 72)
    1761       809425 :         write_char ('\n');
    1762              :       else
    1763              :         {
    1764              : 
    1765     12539505 :           if (last_atom != ATOM_LPAREN && module_column != 1)
    1766     10893314 :             write_char (' ');
    1767              :         }
    1768              :     }
    1769              : 
    1770     13348930 :   if (atom == ATOM_STRING)
    1771      1077346 :     write_char ('\'');
    1772              : 
    1773     68181043 :   while (p != NULL && *p)
    1774              :     {
    1775     50859227 :       if (atom == ATOM_STRING && *p == '\'')
    1776            0 :         write_char ('\'');
    1777     50859227 :       write_char (*p++);
    1778              :     }
    1779              : 
    1780     17321816 :   if (atom == ATOM_STRING)
    1781      1077346 :     write_char ('\'');
    1782              : 
    1783     17321816 :   last_atom = atom;
    1784     17321816 : }
    1785              : 
    1786              : 
    1787              : 
    1788              : /***************** Mid-level I/O subroutines *****************/
    1789              : 
    1790              : /* These subroutines let their caller read or write atoms without
    1791              :    caring about which of the two is actually happening.  This lets a
    1792              :    subroutine concentrate on the actual format of the data being
    1793              :    written.  */
    1794              : 
    1795              : static void mio_expr (gfc_expr **);
    1796              : pointer_info *mio_symbol_ref (gfc_symbol **);
    1797              : pointer_info *mio_interface_rest (gfc_interface **);
    1798              : static void mio_symtree_ref (gfc_symtree **);
    1799              : 
    1800              : /* Read or write an enumerated value.  On writing, we return the input
    1801              :    value for the convenience of callers.  We avoid using an integer
    1802              :    pointer because enums are sometimes inside bitfields.  */
    1803              : 
    1804              : static int
    1805     12791236 : mio_name (int t, const mstring *m)
    1806              : {
    1807     12791236 :   if (iomode == IO_OUTPUT)
    1808      3590125 :     write_atom (ATOM_NAME, gfc_code2string (m, t));
    1809              :   else
    1810              :     {
    1811      9201111 :       require_atom (ATOM_NAME);
    1812      9201111 :       t = find_enum (m);
    1813              :     }
    1814              : 
    1815     12791236 :   return t;
    1816              : }
    1817              : 
    1818              : /* Specialization of mio_name.  */
    1819              : 
    1820              : #define DECL_MIO_NAME(TYPE) \
    1821              :  static inline TYPE \
    1822              :  MIO_NAME(TYPE) (TYPE t, const mstring *m) \
    1823              :  { \
    1824              :    return (TYPE) mio_name ((int) t, m); \
    1825              :  }
    1826              : #define MIO_NAME(TYPE) mio_name_##TYPE
    1827              : 
    1828              : static void
    1829     17062141 : mio_lparen (void)
    1830              : {
    1831     17062141 :   if (iomode == IO_OUTPUT)
    1832      3972886 :     write_atom (ATOM_LPAREN, NULL);
    1833              :   else
    1834     13089255 :     require_atom (ATOM_LPAREN);
    1835     17062141 : }
    1836              : 
    1837              : 
    1838              : static void
    1839     15642345 : mio_rparen (void)
    1840              : {
    1841     15642345 :   if (iomode == IO_OUTPUT)
    1842      3972886 :     write_atom (ATOM_RPAREN, NULL);
    1843              :   else
    1844     11669459 :     require_atom (ATOM_RPAREN);
    1845     15642345 : }
    1846              : 
    1847              : 
    1848              : static void
    1849     12900274 : mio_integer (int *ip)
    1850              : {
    1851     12900274 :   if (iomode == IO_OUTPUT)
    1852              :     {
    1853      2900934 :       HOST_WIDE_INT hwi = *ip;
    1854      2900934 :       write_atom (ATOM_INTEGER, &hwi);
    1855              :     }
    1856              :   else
    1857              :     {
    1858      9999340 :       require_atom (ATOM_INTEGER);
    1859      9999340 :       *ip = atom_int;
    1860              :     }
    1861     12900274 : }
    1862              : 
    1863              : static void
    1864       385603 : mio_hwi (HOST_WIDE_INT *hwi)
    1865              : {
    1866       385603 :   if (iomode == IO_OUTPUT)
    1867       228146 :     write_atom (ATOM_INTEGER, hwi);
    1868              :   else
    1869              :     {
    1870       157457 :       require_atom (ATOM_INTEGER);
    1871       157457 :       *hwi = atom_int;
    1872              :     }
    1873       385603 : }
    1874              : 
    1875              : 
    1876              : /* Read or write a gfc_intrinsic_op value.  */
    1877              : 
    1878              : static void
    1879         1320 : mio_intrinsic_op (gfc_intrinsic_op* op)
    1880              : {
    1881              :   /* FIXME: Would be nicer to do this via the operators symbolic name.  */
    1882         1320 :   if (iomode == IO_OUTPUT)
    1883              :     {
    1884          702 :       HOST_WIDE_INT converted = (HOST_WIDE_INT) *op;
    1885          702 :       write_atom (ATOM_INTEGER, &converted);
    1886              :     }
    1887              :   else
    1888              :     {
    1889          618 :       require_atom (ATOM_INTEGER);
    1890          618 :       *op = (gfc_intrinsic_op) atom_int;
    1891              :     }
    1892         1320 : }
    1893              : 
    1894              : 
    1895              : /* Read or write a character pointer that points to a string on the heap.  */
    1896              : 
    1897              : static const char *
    1898         9054 : mio_allocated_string (const char *s)
    1899              : {
    1900         9054 :   if (iomode == IO_OUTPUT)
    1901              :     {
    1902         9054 :       write_atom (ATOM_STRING, s);
    1903         9054 :       return s;
    1904              :     }
    1905              :   else
    1906              :     {
    1907            0 :       require_atom (ATOM_STRING);
    1908            0 :       return atom_string;
    1909              :     }
    1910              : }
    1911              : 
    1912              : 
    1913              : /* Functions for quoting and unquoting strings.  */
    1914              : 
    1915              : static char *
    1916         5492 : quote_string (const gfc_char_t *s, const size_t slength)
    1917              : {
    1918         5492 :   const gfc_char_t *p;
    1919         5492 :   char *res, *q;
    1920         5492 :   size_t len = 0, i;
    1921              : 
    1922              :   /* Calculate the length we'll need: a backslash takes two ("\\"),
    1923              :      non-printable characters take 10 ("\Uxxxxxxxx") and others take 1.  */
    1924        20519 :   for (p = s, i = 0; i < slength; p++, i++)
    1925              :     {
    1926        15027 :       if (*p == '\\')
    1927            1 :         len += 2;
    1928        15026 :       else if (!gfc_wide_is_printable (*p))
    1929         4739 :         len += 10;
    1930              :       else
    1931        10287 :         len++;
    1932              :     }
    1933              : 
    1934         5492 :   q = res = XCNEWVEC (char, len + 1);
    1935        26011 :   for (p = s, i = 0; i < slength; p++, i++)
    1936              :     {
    1937        15027 :       if (*p == '\\')
    1938            1 :         *q++ = '\\', *q++ = '\\';
    1939        15026 :       else if (!gfc_wide_is_printable (*p))
    1940              :         {
    1941         4739 :           sprintf (q, "\\U%08" HOST_WIDE_INT_PRINT "x",
    1942         4739 :                    (unsigned HOST_WIDE_INT) *p);
    1943         4739 :           q += 10;
    1944              :         }
    1945              :       else
    1946        10287 :         *q++ = (unsigned char) *p;
    1947              :     }
    1948              : 
    1949         5492 :   res[len] = '\0';
    1950         5492 :   return res;
    1951              : }
    1952              : 
    1953              : static gfc_char_t *
    1954         2970 : unquote_string (const char *s)
    1955              : {
    1956         2970 :   size_t len, i;
    1957         2970 :   const char *p;
    1958         2970 :   gfc_char_t *res;
    1959              : 
    1960        14666 :   for (p = s, len = 0; *p; p++, len++)
    1961              :     {
    1962        11696 :       if (*p != '\\')
    1963         9534 :         continue;
    1964              : 
    1965         2162 :       if (p[1] == '\\')
    1966            0 :         p++;
    1967         2162 :       else if (p[1] == 'U')
    1968         2162 :         p += 9; /* That is a "\U????????".  */
    1969              :       else
    1970            0 :         gfc_internal_error ("unquote_string(): got bad string");
    1971              :     }
    1972              : 
    1973         2970 :   res = gfc_get_wide_string (len + 1);
    1974        14666 :   for (i = 0, p = s; i < len; i++, p++)
    1975              :     {
    1976        11696 :       gcc_assert (*p);
    1977              : 
    1978        11696 :       if (*p != '\\')
    1979         9534 :         res[i] = (unsigned char) *p;
    1980         2162 :       else if (p[1] == '\\')
    1981              :         {
    1982            0 :           res[i] = (unsigned char) '\\';
    1983            0 :           p++;
    1984              :         }
    1985              :       else
    1986              :         {
    1987              :           /* We read the 8-digits hexadecimal constant that follows.  */
    1988         2162 :           int j;
    1989         2162 :           unsigned n;
    1990         2162 :           gfc_char_t c = 0;
    1991              : 
    1992         2162 :           gcc_assert (p[1] == 'U');
    1993        19458 :           for (j = 0; j < 8; j++)
    1994              :             {
    1995        17296 :               c = c << 4;
    1996        17296 :               gcc_assert (sscanf (&p[j+2], "%01x", &n) == 1);
    1997        17296 :               c += n;
    1998              :             }
    1999              : 
    2000         2162 :           res[i] = c;
    2001         2162 :           p += 9;
    2002              :         }
    2003              :     }
    2004              : 
    2005         2970 :   res[len] = '\0';
    2006         2970 :   return res;
    2007              : }
    2008              : 
    2009              : 
    2010              : /* Read or write a character pointer that points to a wide string on the
    2011              :    heap, performing quoting/unquoting of nonprintable characters using the
    2012              :    form \U???????? (where each ? is a hexadecimal digit).
    2013              :    Length is the length of the string, only known and used in output mode.  */
    2014              : 
    2015              : static const gfc_char_t *
    2016         8462 : mio_allocated_wide_string (const gfc_char_t *s, const size_t length)
    2017              : {
    2018         8462 :   if (iomode == IO_OUTPUT)
    2019              :     {
    2020         5492 :       char *quoted = quote_string (s, length);
    2021         5492 :       write_atom (ATOM_STRING, quoted);
    2022         5492 :       free (quoted);
    2023         5492 :       return s;
    2024              :     }
    2025              :   else
    2026              :     {
    2027         2970 :       gfc_char_t *unquoted;
    2028              : 
    2029         2970 :       require_atom (ATOM_STRING);
    2030         2970 :       unquoted = unquote_string (atom_string);
    2031         2970 :       free (atom_string);
    2032         2970 :       return unquoted;
    2033              :     }
    2034              : }
    2035              : 
    2036              : 
    2037              : /* Read or write a string that is in static memory.  */
    2038              : 
    2039              : static void
    2040       984728 : mio_pool_string (const char **stringp)
    2041              : {
    2042              :   /* TODO: one could write the string only once, and refer to it via a
    2043              :      fixup pointer.  */
    2044              : 
    2045              :   /* As a special case we have to deal with a NULL string.  This
    2046              :      happens for the 'module' member of 'gfc_symbol's that are not in a
    2047              :      module.  We read / write these as the empty string.  */
    2048       984728 :   if (iomode == IO_OUTPUT)
    2049              :     {
    2050       760122 :       const char *p = *stringp == NULL ? "" : *stringp;
    2051       760122 :       write_atom (ATOM_STRING, p);
    2052              :     }
    2053              :   else
    2054              :     {
    2055       224606 :       require_atom (ATOM_STRING);
    2056       449212 :       *stringp = (atom_string[0] == '\0'
    2057       224606 :                   ? NULL : gfc_get_string ("%s", atom_string));
    2058       224606 :       free (atom_string);
    2059              :     }
    2060       984728 : }
    2061              : 
    2062              : 
    2063              : /* Read or write a string that is inside of some already-allocated
    2064              :    structure.  */
    2065              : 
    2066              : static void
    2067       598979 : mio_internal_string (char *string)
    2068              : {
    2069       598979 :   if (iomode == IO_OUTPUT)
    2070            0 :     write_atom (ATOM_STRING, string);
    2071              :   else
    2072              :     {
    2073       598979 :       require_atom (ATOM_STRING);
    2074       598979 :       strcpy (string, atom_string);
    2075       598979 :       free (atom_string);
    2076              :     }
    2077       598979 : }
    2078              : 
    2079              : 
    2080              : enum ab_attribute
    2081              : { AB_ALLOCATABLE, AB_DIMENSION, AB_EXTERNAL, AB_INTRINSIC, AB_OPTIONAL,
    2082              :   AB_POINTER, AB_TARGET, AB_DUMMY, AB_RESULT, AB_DATA,
    2083              :   AB_IN_NAMELIST, AB_IN_COMMON, AB_FUNCTION, AB_SUBROUTINE, AB_SEQUENCE,
    2084              :   AB_ELEMENTAL, AB_PURE, AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT,
    2085              :   AB_CRAY_POINTER, AB_CRAY_POINTEE, AB_THREADPRIVATE,
    2086              :   AB_ALLOC_COMP, AB_POINTER_COMP, AB_PROC_POINTER_COMP, AB_PRIVATE_COMP,
    2087              :   AB_VALUE, AB_VOLATILE, AB_PROTECTED, AB_LOCK_COMP, AB_EVENT_COMP,
    2088              :   AB_IS_BIND_C, AB_IS_C_INTEROP, AB_IS_ISO_C, AB_ABSTRACT, AB_ZERO_COMP,
    2089              :   AB_IS_CLASS, AB_PROCEDURE, AB_PROC_POINTER, AB_ASYNCHRONOUS, AB_CODIMENSION,
    2090              :   AB_COARRAY_COMP, AB_VTYPE, AB_VTAB, AB_CONTIGUOUS, AB_CLASS_POINTER,
    2091              :   AB_IMPLICIT_PURE, AB_ARTIFICIAL, AB_UNLIMITED_POLY, AB_OMP_DECLARE_TARGET,
    2092              :   AB_ARRAY_OUTER_DEPENDENCY, AB_MODULE_PROCEDURE, AB_OACC_DECLARE_CREATE,
    2093              :   AB_OACC_DECLARE_COPYIN, AB_OACC_DECLARE_DEVICEPTR,
    2094              :   AB_OACC_DECLARE_DEVICE_RESIDENT, AB_OACC_DECLARE_LINK,
    2095              :   AB_OMP_DECLARE_TARGET_LINK, AB_OMP_DECLARE_TARGET_LOCAL,
    2096              :   AB_PDT_KIND, AB_PDT_LEN, AB_PDT_TYPE,
    2097              :   AB_PDT_COMP, AB_PDT_TEMPLATE, AB_PDT_ARRAY, AB_PDT_STRING,
    2098              :   AB_OACC_ROUTINE_LOP_GANG, AB_OACC_ROUTINE_LOP_WORKER,
    2099              :   AB_OACC_ROUTINE_LOP_VECTOR, AB_OACC_ROUTINE_LOP_SEQ,
    2100              :   AB_OACC_ROUTINE_NOHOST,
    2101              :   AB_OMP_REQ_REVERSE_OFFLOAD, AB_OMP_REQ_UNIFIED_ADDRESS, AB_OMP_REQ_SELF_MAPS,
    2102              :   AB_OMP_REQ_UNIFIED_SHARED_MEMORY, AB_OMP_REQ_DYNAMIC_ALLOCATORS,
    2103              :   AB_OMP_REQ_MEM_ORDER_SEQ_CST, AB_OMP_REQ_MEM_ORDER_ACQ_REL,
    2104              :   AB_OMP_REQ_MEM_ORDER_ACQUIRE, AB_OMP_REQ_MEM_ORDER_RELEASE,
    2105              :   AB_OMP_REQ_MEM_ORDER_RELAXED, AB_OMP_DEVICE_TYPE_NOHOST,
    2106              :   AB_OMP_DEVICE_TYPE_HOST, AB_OMP_DEVICE_TYPE_ANY, AB_OMP_GROUPPRIVATE
    2107              : };
    2108              : 
    2109              : static const mstring attr_bits[] =
    2110              : {
    2111              :     minit ("ALLOCATABLE", AB_ALLOCATABLE),
    2112              :     minit ("ARTIFICIAL", AB_ARTIFICIAL),
    2113              :     minit ("ASYNCHRONOUS", AB_ASYNCHRONOUS),
    2114              :     minit ("DIMENSION", AB_DIMENSION),
    2115              :     minit ("CODIMENSION", AB_CODIMENSION),
    2116              :     minit ("CONTIGUOUS", AB_CONTIGUOUS),
    2117              :     minit ("EXTERNAL", AB_EXTERNAL),
    2118              :     minit ("INTRINSIC", AB_INTRINSIC),
    2119              :     minit ("OPTIONAL", AB_OPTIONAL),
    2120              :     minit ("POINTER", AB_POINTER),
    2121              :     minit ("VOLATILE", AB_VOLATILE),
    2122              :     minit ("TARGET", AB_TARGET),
    2123              :     minit ("THREADPRIVATE", AB_THREADPRIVATE),
    2124              :     minit ("DUMMY", AB_DUMMY),
    2125              :     minit ("RESULT", AB_RESULT),
    2126              :     minit ("DATA", AB_DATA),
    2127              :     minit ("IN_NAMELIST", AB_IN_NAMELIST),
    2128              :     minit ("IN_COMMON", AB_IN_COMMON),
    2129              :     minit ("FUNCTION", AB_FUNCTION),
    2130              :     minit ("SUBROUTINE", AB_SUBROUTINE),
    2131              :     minit ("SEQUENCE", AB_SEQUENCE),
    2132              :     minit ("ELEMENTAL", AB_ELEMENTAL),
    2133              :     minit ("PURE", AB_PURE),
    2134              :     minit ("RECURSIVE", AB_RECURSIVE),
    2135              :     minit ("GENERIC", AB_GENERIC),
    2136              :     minit ("ALWAYS_EXPLICIT", AB_ALWAYS_EXPLICIT),
    2137              :     minit ("CRAY_POINTER", AB_CRAY_POINTER),
    2138              :     minit ("CRAY_POINTEE", AB_CRAY_POINTEE),
    2139              :     minit ("IS_BIND_C", AB_IS_BIND_C),
    2140              :     minit ("IS_C_INTEROP", AB_IS_C_INTEROP),
    2141              :     minit ("IS_ISO_C", AB_IS_ISO_C),
    2142              :     minit ("VALUE", AB_VALUE),
    2143              :     minit ("ALLOC_COMP", AB_ALLOC_COMP),
    2144              :     minit ("COARRAY_COMP", AB_COARRAY_COMP),
    2145              :     minit ("LOCK_COMP", AB_LOCK_COMP),
    2146              :     minit ("EVENT_COMP", AB_EVENT_COMP),
    2147              :     minit ("POINTER_COMP", AB_POINTER_COMP),
    2148              :     minit ("PROC_POINTER_COMP", AB_PROC_POINTER_COMP),
    2149              :     minit ("PRIVATE_COMP", AB_PRIVATE_COMP),
    2150              :     minit ("ZERO_COMP", AB_ZERO_COMP),
    2151              :     minit ("PROTECTED", AB_PROTECTED),
    2152              :     minit ("ABSTRACT", AB_ABSTRACT),
    2153              :     minit ("IS_CLASS", AB_IS_CLASS),
    2154              :     minit ("PROCEDURE", AB_PROCEDURE),
    2155              :     minit ("PROC_POINTER", AB_PROC_POINTER),
    2156              :     minit ("VTYPE", AB_VTYPE),
    2157              :     minit ("VTAB", AB_VTAB),
    2158              :     minit ("CLASS_POINTER", AB_CLASS_POINTER),
    2159              :     minit ("IMPLICIT_PURE", AB_IMPLICIT_PURE),
    2160              :     minit ("UNLIMITED_POLY", AB_UNLIMITED_POLY),
    2161              :     minit ("OMP_DECLARE_TARGET", AB_OMP_DECLARE_TARGET),
    2162              :     minit ("ARRAY_OUTER_DEPENDENCY", AB_ARRAY_OUTER_DEPENDENCY),
    2163              :     minit ("MODULE_PROCEDURE", AB_MODULE_PROCEDURE),
    2164              :     minit ("OACC_DECLARE_CREATE", AB_OACC_DECLARE_CREATE),
    2165              :     minit ("OACC_DECLARE_COPYIN", AB_OACC_DECLARE_COPYIN),
    2166              :     minit ("OACC_DECLARE_DEVICEPTR", AB_OACC_DECLARE_DEVICEPTR),
    2167              :     minit ("OACC_DECLARE_DEVICE_RESIDENT", AB_OACC_DECLARE_DEVICE_RESIDENT),
    2168              :     minit ("OACC_DECLARE_LINK", AB_OACC_DECLARE_LINK),
    2169              :     minit ("OMP_DECLARE_TARGET_LINK", AB_OMP_DECLARE_TARGET_LINK),
    2170              :     minit ("OMP_DECLARE_TARGET_LOCAL", AB_OMP_DECLARE_TARGET_LOCAL),
    2171              :     minit ("OMP_GROUPPRIVATE", AB_OMP_GROUPPRIVATE),
    2172              :     minit ("PDT_KIND", AB_PDT_KIND),
    2173              :     minit ("PDT_LEN", AB_PDT_LEN),
    2174              :     minit ("PDT_TYPE", AB_PDT_TYPE),
    2175              :     minit ("PDT_TEMPLATE", AB_PDT_TEMPLATE),
    2176              :     minit ("PDT_ARRAY", AB_PDT_ARRAY),
    2177              :     minit ("PDT_STRING", AB_PDT_STRING),
    2178              :     minit ("PDT_COMP", AB_PDT_COMP),
    2179              :     minit ("OACC_ROUTINE_LOP_GANG", AB_OACC_ROUTINE_LOP_GANG),
    2180              :     minit ("OACC_ROUTINE_LOP_WORKER", AB_OACC_ROUTINE_LOP_WORKER),
    2181              :     minit ("OACC_ROUTINE_LOP_VECTOR", AB_OACC_ROUTINE_LOP_VECTOR),
    2182              :     minit ("OACC_ROUTINE_LOP_SEQ", AB_OACC_ROUTINE_LOP_SEQ),
    2183              :     minit ("OACC_ROUTINE_NOHOST", AB_OACC_ROUTINE_NOHOST),
    2184              :     minit ("OMP_REQ_REVERSE_OFFLOAD", AB_OMP_REQ_REVERSE_OFFLOAD),
    2185              :     minit ("OMP_REQ_UNIFIED_ADDRESS", AB_OMP_REQ_UNIFIED_ADDRESS),
    2186              :     minit ("OMP_REQ_UNIFIED_SHARED_MEMORY", AB_OMP_REQ_UNIFIED_SHARED_MEMORY),
    2187              :     minit ("OMP_REQ_SELF_MAPS", AB_OMP_REQ_SELF_MAPS),
    2188              :     minit ("OMP_REQ_DYNAMIC_ALLOCATORS", AB_OMP_REQ_DYNAMIC_ALLOCATORS),
    2189              :     minit ("OMP_REQ_MEM_ORDER_SEQ_CST", AB_OMP_REQ_MEM_ORDER_SEQ_CST),
    2190              :     minit ("OMP_REQ_MEM_ORDER_ACQ_REL", AB_OMP_REQ_MEM_ORDER_ACQ_REL),
    2191              :     minit ("OMP_REQ_MEM_ORDER_ACQUIRE", AB_OMP_REQ_MEM_ORDER_ACQUIRE),
    2192              :     minit ("OMP_REQ_MEM_ORDER_RELAXED", AB_OMP_REQ_MEM_ORDER_RELAXED),
    2193              :     minit ("OMP_REQ_MEM_ORDER_RELEASE", AB_OMP_REQ_MEM_ORDER_RELEASE),
    2194              :     minit ("OMP_DEVICE_TYPE_HOST", AB_OMP_DEVICE_TYPE_HOST),
    2195              :     minit ("OMP_DEVICE_TYPE_NOHOST", AB_OMP_DEVICE_TYPE_NOHOST),
    2196              :     minit ("OMP_DEVICE_TYPE_ANYHOST", AB_OMP_DEVICE_TYPE_ANY),
    2197              :     minit (NULL, -1)
    2198              : };
    2199              : 
    2200              : /* For binding attributes.  */
    2201              : static const mstring binding_passing[] =
    2202              : {
    2203              :     minit ("PASS", 0),
    2204              :     minit ("NOPASS", 1),
    2205              :     minit (NULL, -1)
    2206              : };
    2207              : static const mstring binding_overriding[] =
    2208              : {
    2209              :     minit ("OVERRIDABLE", 0),
    2210              :     minit ("NON_OVERRIDABLE", 1),
    2211              :     minit ("DEFERRED", 2),
    2212              :     minit (NULL, -1)
    2213              : };
    2214              : static const mstring binding_generic[] =
    2215              : {
    2216              :     minit ("SPECIFIC", 0),
    2217              :     minit ("GENERIC", 1),
    2218              :     minit (NULL, -1)
    2219              : };
    2220              : static const mstring binding_ppc[] =
    2221              : {
    2222              :     minit ("NO_PPC", 0),
    2223              :     minit ("PPC", 1),
    2224              :     minit (NULL, -1)
    2225              : };
    2226              : 
    2227              : /* Specialization of mio_name.  */
    2228       598101 : DECL_MIO_NAME (ab_attribute)
    2229         3534 : DECL_MIO_NAME (ar_type)
    2230       160806 : DECL_MIO_NAME (array_type)
    2231      7573104 : DECL_MIO_NAME (bt)
    2232        98633 : DECL_MIO_NAME (expr_t)
    2233       594019 : DECL_MIO_NAME (gfc_access)
    2234         1589 : DECL_MIO_NAME (gfc_intrinsic_op)
    2235      1482074 : DECL_MIO_NAME (ifsrc)
    2236      1482074 : DECL_MIO_NAME (save_state)
    2237      1482074 : DECL_MIO_NAME (procedure_type)
    2238         5006 : DECL_MIO_NAME (ref_type)
    2239      1482074 : DECL_MIO_NAME (sym_flavor)
    2240      1482074 : DECL_MIO_NAME (sym_intent)
    2241            0 : DECL_MIO_NAME (inquiry_type)
    2242              : #undef DECL_MIO_NAME
    2243              : 
    2244              : /* Verify OACC_ROUTINE_LOP_NONE.  */
    2245              : 
    2246              : static void
    2247           96 : verify_OACC_ROUTINE_LOP_NONE (enum oacc_routine_lop lop)
    2248              : {
    2249            0 :   if (lop != OACC_ROUTINE_LOP_NONE)
    2250            0 :     bad_module ("Unsupported: multiple OpenACC 'routine' levels of parallelism");
    2251            0 : }
    2252              : 
    2253              : /* Symbol attributes are stored in list with the first three elements
    2254              :    being the enumerated fields, while the remaining elements (if any)
    2255              :    indicate the individual attribute bits.  The access field is not
    2256              :    saved-- it controls what symbols are exported when a module is
    2257              :    written.  */
    2258              : 
    2259              : static void
    2260      1482074 : mio_symbol_attribute (symbol_attribute *attr)
    2261              : {
    2262      1482074 :   atom_type t;
    2263      1482074 :   unsigned ext_attr,extension_level;
    2264              : 
    2265      1482074 :   mio_lparen ();
    2266              : 
    2267      1482074 :   attr->flavor = MIO_NAME (sym_flavor) (attr->flavor, flavors);
    2268      1482074 :   attr->intent = MIO_NAME (sym_intent) (attr->intent, intents);
    2269      1482074 :   attr->proc = MIO_NAME (procedure_type) (attr->proc, procedures);
    2270      1482074 :   attr->if_source = MIO_NAME (ifsrc) (attr->if_source, ifsrc_types);
    2271      1482074 :   attr->save = MIO_NAME (save_state) (attr->save, save_status);
    2272              : 
    2273      1482074 :   ext_attr = attr->ext_attr;
    2274      1482074 :   mio_integer ((int *) &ext_attr);
    2275      1482074 :   attr->ext_attr = ext_attr;
    2276              : 
    2277      1482074 :   extension_level = attr->extension;
    2278      1482074 :   mio_integer ((int *) &extension_level);
    2279      1482074 :   attr->extension = extension_level;
    2280              : 
    2281      1482074 :   if (iomode == IO_OUTPUT)
    2282              :     {
    2283       334084 :       if (attr->allocatable)
    2284         4711 :         MIO_NAME (ab_attribute) (AB_ALLOCATABLE, attr_bits);
    2285       334084 :       if (attr->artificial)
    2286        97977 :         MIO_NAME (ab_attribute) (AB_ARTIFICIAL, attr_bits);
    2287       334084 :       if (attr->asynchronous)
    2288            0 :         MIO_NAME (ab_attribute) (AB_ASYNCHRONOUS, attr_bits);
    2289       334084 :       if (attr->dimension)
    2290        18045 :         MIO_NAME (ab_attribute) (AB_DIMENSION, attr_bits);
    2291       334084 :       if (attr->codimension)
    2292           98 :         MIO_NAME (ab_attribute) (AB_CODIMENSION, attr_bits);
    2293       334084 :       if (attr->contiguous)
    2294         3047 :         MIO_NAME (ab_attribute) (AB_CONTIGUOUS, attr_bits);
    2295       334084 :       if (attr->external)
    2296        14783 :         MIO_NAME (ab_attribute) (AB_EXTERNAL, attr_bits);
    2297       334084 :       if (attr->intrinsic)
    2298         4967 :         MIO_NAME (ab_attribute) (AB_INTRINSIC, attr_bits);
    2299       334084 :       if (attr->optional)
    2300         4584 :         MIO_NAME (ab_attribute) (AB_OPTIONAL, attr_bits);
    2301       334084 :       if (attr->pointer)
    2302        31127 :         MIO_NAME (ab_attribute) (AB_POINTER, attr_bits);
    2303       334084 :       if (attr->class_pointer)
    2304          473 :         MIO_NAME (ab_attribute) (AB_CLASS_POINTER, attr_bits);
    2305       334084 :       if (attr->is_protected)
    2306           70 :         MIO_NAME (ab_attribute) (AB_PROTECTED, attr_bits);
    2307       334084 :       if (attr->value)
    2308        10510 :         MIO_NAME (ab_attribute) (AB_VALUE, attr_bits);
    2309       334084 :       if (attr->volatile_)
    2310           14 :         MIO_NAME (ab_attribute) (AB_VOLATILE, attr_bits);
    2311       334084 :       if (attr->target)
    2312        18923 :         MIO_NAME (ab_attribute) (AB_TARGET, attr_bits);
    2313       334084 :       if (attr->threadprivate)
    2314           42 :         MIO_NAME (ab_attribute) (AB_THREADPRIVATE, attr_bits);
    2315       334084 :       if (attr->dummy)
    2316        78513 :         MIO_NAME (ab_attribute) (AB_DUMMY, attr_bits);
    2317       334084 :       if (attr->result)
    2318         6855 :         MIO_NAME (ab_attribute) (AB_RESULT, attr_bits);
    2319              :       /* We deliberately don't preserve the "entry" flag.  */
    2320              : 
    2321       334084 :       if (attr->data)
    2322           22 :         MIO_NAME (ab_attribute) (AB_DATA, attr_bits);
    2323       334084 :       if (attr->in_namelist)
    2324           78 :         MIO_NAME (ab_attribute) (AB_IN_NAMELIST, attr_bits);
    2325       334084 :       if (attr->in_common)
    2326          392 :         MIO_NAME (ab_attribute) (AB_IN_COMMON, attr_bits);
    2327              : 
    2328       334084 :       if (attr->function)
    2329        32958 :         MIO_NAME (ab_attribute) (AB_FUNCTION, attr_bits);
    2330       334084 :       if (attr->subroutine)
    2331        27987 :         MIO_NAME (ab_attribute) (AB_SUBROUTINE, attr_bits);
    2332       334084 :       if (attr->generic)
    2333         9030 :         MIO_NAME (ab_attribute) (AB_GENERIC, attr_bits);
    2334       334084 :       if (attr->abstract)
    2335         2962 :         MIO_NAME (ab_attribute) (AB_ABSTRACT, attr_bits);
    2336              : 
    2337       334084 :       if (attr->sequence)
    2338          125 :         MIO_NAME (ab_attribute) (AB_SEQUENCE, attr_bits);
    2339       334084 :       if (attr->elemental)
    2340        15223 :         MIO_NAME (ab_attribute) (AB_ELEMENTAL, attr_bits);
    2341       334084 :       if (attr->pure)
    2342        18595 :         MIO_NAME (ab_attribute) (AB_PURE, attr_bits);
    2343       334084 :       if (attr->implicit_pure)
    2344         4108 :         MIO_NAME (ab_attribute) (AB_IMPLICIT_PURE, attr_bits);
    2345       334084 :       if (attr->unlimited_polymorphic)
    2346          343 :         MIO_NAME (ab_attribute) (AB_UNLIMITED_POLY, attr_bits);
    2347       334084 :       if (attr->recursive)
    2348         2767 :         MIO_NAME (ab_attribute) (AB_RECURSIVE, attr_bits);
    2349       334084 :       if (attr->always_explicit)
    2350        29215 :         MIO_NAME (ab_attribute) (AB_ALWAYS_EXPLICIT, attr_bits);
    2351       334084 :       if (attr->cray_pointer)
    2352           13 :         MIO_NAME (ab_attribute) (AB_CRAY_POINTER, attr_bits);
    2353       334084 :       if (attr->cray_pointee)
    2354           13 :         MIO_NAME (ab_attribute) (AB_CRAY_POINTEE, attr_bits);
    2355       334084 :       if (attr->is_bind_c)
    2356         6379 :         MIO_NAME(ab_attribute) (AB_IS_BIND_C, attr_bits);
    2357       334084 :       if (attr->is_c_interop)
    2358        29991 :         MIO_NAME(ab_attribute) (AB_IS_C_INTEROP, attr_bits);
    2359       334084 :       if (attr->is_iso_c)
    2360        26301 :         MIO_NAME(ab_attribute) (AB_IS_ISO_C, attr_bits);
    2361       334084 :       if (attr->alloc_comp)
    2362         2756 :         MIO_NAME (ab_attribute) (AB_ALLOC_COMP, attr_bits);
    2363       334084 :       if (attr->pointer_comp)
    2364          937 :         MIO_NAME (ab_attribute) (AB_POINTER_COMP, attr_bits);
    2365       334084 :       if (attr->proc_pointer_comp)
    2366          258 :         MIO_NAME (ab_attribute) (AB_PROC_POINTER_COMP, attr_bits);
    2367       334084 :       if (attr->private_comp)
    2368         3243 :         MIO_NAME (ab_attribute) (AB_PRIVATE_COMP, attr_bits);
    2369       334084 :       if (attr->coarray_comp)
    2370           33 :         MIO_NAME (ab_attribute) (AB_COARRAY_COMP, attr_bits);
    2371       334084 :       if (attr->lock_comp)
    2372            4 :         MIO_NAME (ab_attribute) (AB_LOCK_COMP, attr_bits);
    2373       334084 :       if (attr->event_comp)
    2374            0 :         MIO_NAME (ab_attribute) (AB_EVENT_COMP, attr_bits);
    2375       334084 :       if (attr->zero_comp)
    2376         2126 :         MIO_NAME (ab_attribute) (AB_ZERO_COMP, attr_bits);
    2377       334084 :       if (attr->is_class)
    2378         4528 :         MIO_NAME (ab_attribute) (AB_IS_CLASS, attr_bits);
    2379       334084 :       if (attr->procedure)
    2380         5545 :         MIO_NAME (ab_attribute) (AB_PROCEDURE, attr_bits);
    2381       334084 :       if (attr->proc_pointer)
    2382        35931 :         MIO_NAME (ab_attribute) (AB_PROC_POINTER, attr_bits);
    2383       334084 :       if (attr->vtype)
    2384        10261 :         MIO_NAME (ab_attribute) (AB_VTYPE, attr_bits);
    2385       334084 :       if (attr->vtab)
    2386         9724 :         MIO_NAME (ab_attribute) (AB_VTAB, attr_bits);
    2387       334084 :       if (attr->omp_declare_target)
    2388          418 :         MIO_NAME (ab_attribute) (AB_OMP_DECLARE_TARGET, attr_bits);
    2389       334084 :       if (attr->array_outer_dependency)
    2390        17447 :         MIO_NAME (ab_attribute) (AB_ARRAY_OUTER_DEPENDENCY, attr_bits);
    2391       334084 :       if (attr->module_procedure)
    2392         1499 :         MIO_NAME (ab_attribute) (AB_MODULE_PROCEDURE, attr_bits);
    2393       334084 :       if (attr->oacc_declare_create)
    2394           39 :         MIO_NAME (ab_attribute) (AB_OACC_DECLARE_CREATE, attr_bits);
    2395       334084 :       if (attr->oacc_declare_copyin)
    2396            3 :         MIO_NAME (ab_attribute) (AB_OACC_DECLARE_COPYIN, attr_bits);
    2397       334084 :       if (attr->oacc_declare_deviceptr)
    2398            1 :         MIO_NAME (ab_attribute) (AB_OACC_DECLARE_DEVICEPTR, attr_bits);
    2399       334084 :       if (attr->oacc_declare_device_resident)
    2400           33 :         MIO_NAME (ab_attribute) (AB_OACC_DECLARE_DEVICE_RESIDENT, attr_bits);
    2401       334084 :       if (attr->oacc_declare_link)
    2402            1 :         MIO_NAME (ab_attribute) (AB_OACC_DECLARE_LINK, attr_bits);
    2403       334084 :       if (attr->omp_declare_target_link)
    2404           15 :         MIO_NAME (ab_attribute) (AB_OMP_DECLARE_TARGET_LINK, attr_bits);
    2405       334084 :       if (attr->omp_declare_target_local)
    2406           12 :         MIO_NAME (ab_attribute) (AB_OMP_DECLARE_TARGET_LOCAL, attr_bits);
    2407       334084 :       if (attr->omp_groupprivate)
    2408           12 :         MIO_NAME (ab_attribute) (AB_OMP_GROUPPRIVATE, attr_bits);
    2409       334084 :       if (attr->pdt_kind)
    2410          552 :         MIO_NAME (ab_attribute) (AB_PDT_KIND, attr_bits);
    2411       334084 :       if (attr->pdt_len)
    2412          395 :         MIO_NAME (ab_attribute) (AB_PDT_LEN, attr_bits);
    2413       334084 :       if (attr->pdt_type)
    2414          285 :         MIO_NAME (ab_attribute) (AB_PDT_TYPE, attr_bits);
    2415       334084 :       if (attr->pdt_comp)
    2416           27 :         MIO_NAME (ab_attribute) (AB_PDT_COMP , attr_bits);
    2417       334084 :       if (attr->pdt_template)
    2418          237 :         MIO_NAME (ab_attribute) (AB_PDT_TEMPLATE, attr_bits);
    2419       334084 :       if (attr->pdt_array)
    2420           65 :         MIO_NAME (ab_attribute) (AB_PDT_ARRAY, attr_bits);
    2421       334084 :       if (attr->pdt_string)
    2422            2 :         MIO_NAME (ab_attribute) (AB_PDT_STRING, attr_bits);
    2423       334084 :       switch (attr->oacc_routine_lop)
    2424              :         {
    2425              :         case OACC_ROUTINE_LOP_NONE:
    2426              :           /* This is the default anyway, and for maintaining compatibility with
    2427              :              the current MOD_VERSION, we're not emitting anything in that
    2428              :              case.  */
    2429              :           break;
    2430           12 :         case OACC_ROUTINE_LOP_GANG:
    2431           12 :           MIO_NAME (ab_attribute) (AB_OACC_ROUTINE_LOP_GANG, attr_bits);
    2432           12 :           break;
    2433           10 :         case OACC_ROUTINE_LOP_WORKER:
    2434           10 :           MIO_NAME (ab_attribute) (AB_OACC_ROUTINE_LOP_WORKER, attr_bits);
    2435           10 :           break;
    2436            8 :         case OACC_ROUTINE_LOP_VECTOR:
    2437            8 :           MIO_NAME (ab_attribute) (AB_OACC_ROUTINE_LOP_VECTOR, attr_bits);
    2438            8 :           break;
    2439           81 :         case OACC_ROUTINE_LOP_SEQ:
    2440           81 :           MIO_NAME (ab_attribute) (AB_OACC_ROUTINE_LOP_SEQ, attr_bits);
    2441           81 :           break;
    2442            0 :         case OACC_ROUTINE_LOP_ERROR:
    2443              :           /* ... intentionally omitted here; it's only used internally.  */
    2444            0 :         default:
    2445            0 :           gcc_unreachable ();
    2446              :         }
    2447       334084 :       if (attr->oacc_routine_nohost)
    2448           21 :         MIO_NAME (ab_attribute) (AB_OACC_ROUTINE_NOHOST, attr_bits);
    2449              : 
    2450       334084 :       if (attr->flavor == FL_MODULE && gfc_current_ns->omp_requires)
    2451              :         {
    2452           29 :           if (gfc_current_ns->omp_requires & OMP_REQ_REVERSE_OFFLOAD)
    2453           15 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_REVERSE_OFFLOAD, attr_bits);
    2454           29 :           if (gfc_current_ns->omp_requires & OMP_REQ_UNIFIED_ADDRESS)
    2455            1 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_UNIFIED_ADDRESS, attr_bits);
    2456           29 :           if (gfc_current_ns->omp_requires & OMP_REQ_UNIFIED_SHARED_MEMORY)
    2457            3 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_UNIFIED_SHARED_MEMORY, attr_bits);
    2458           29 :           if (gfc_current_ns->omp_requires & OMP_REQ_SELF_MAPS)
    2459            1 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_SELF_MAPS, attr_bits);
    2460           29 :           if (gfc_current_ns->omp_requires & OMP_REQ_DYNAMIC_ALLOCATORS)
    2461            2 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_DYNAMIC_ALLOCATORS, attr_bits);
    2462           29 :           if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
    2463              :               == OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST)
    2464            3 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_SEQ_CST, attr_bits);
    2465           29 :           if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
    2466              :               == OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL)
    2467            3 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_ACQ_REL, attr_bits);
    2468           29 :           if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
    2469              :               == OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE)
    2470            0 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_ACQUIRE, attr_bits);
    2471           29 :           if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
    2472              :               == OMP_REQ_ATOMIC_MEM_ORDER_RELAXED)
    2473            3 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_RELAXED, attr_bits);
    2474           29 :           if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK)
    2475              :               == OMP_REQ_ATOMIC_MEM_ORDER_RELEASE)
    2476            0 :             MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_RELEASE, attr_bits);
    2477              :         }
    2478       334084 :       switch (attr->omp_device_type)
    2479              :         {
    2480              :         case OMP_DEVICE_TYPE_UNSET:
    2481              :           break;
    2482           16 :         case OMP_DEVICE_TYPE_HOST:
    2483           16 :           MIO_NAME (ab_attribute) (AB_OMP_DEVICE_TYPE_HOST, attr_bits);
    2484           16 :           break;
    2485            9 :         case OMP_DEVICE_TYPE_NOHOST:
    2486            9 :           MIO_NAME (ab_attribute) (AB_OMP_DEVICE_TYPE_NOHOST, attr_bits);
    2487            9 :           break;
    2488          283 :         case OMP_DEVICE_TYPE_ANY:
    2489          283 :           MIO_NAME (ab_attribute) (AB_OMP_DEVICE_TYPE_ANY, attr_bits);
    2490          283 :           break;
    2491            0 :         default:
    2492            0 :           gcc_unreachable ();
    2493              :         }
    2494       334084 :       mio_rparen ();
    2495              :     }
    2496              :   else
    2497              :     {
    2498      3252019 :       for (;;)
    2499              :         {
    2500      3252019 :           t = parse_atom ();
    2501      3252019 :           if (t == ATOM_RPAREN)
    2502              :             break;
    2503      2104029 :           if (t != ATOM_NAME)
    2504            0 :             bad_module ("Expected attribute bit name");
    2505              : 
    2506      2104029 :           switch ((ab_attribute) find_enum (attr_bits))
    2507              :             {
    2508         4577 :             case AB_ALLOCATABLE:
    2509         4577 :               attr->allocatable = 1;
    2510         4577 :               break;
    2511       138144 :             case AB_ARTIFICIAL:
    2512       138144 :               attr->artificial = 1;
    2513       138144 :               break;
    2514            0 :             case AB_ASYNCHRONOUS:
    2515            0 :               attr->asynchronous = 1;
    2516            0 :               break;
    2517        62228 :             case AB_DIMENSION:
    2518        62228 :               attr->dimension = 1;
    2519        62228 :               break;
    2520           94 :             case AB_CODIMENSION:
    2521           94 :               attr->codimension = 1;
    2522           94 :               break;
    2523         7737 :             case AB_CONTIGUOUS:
    2524         7737 :               attr->contiguous = 1;
    2525         7737 :               break;
    2526       182218 :             case AB_EXTERNAL:
    2527       182218 :               attr->external = 1;
    2528       182218 :               break;
    2529         3355 :             case AB_INTRINSIC:
    2530         3355 :               attr->intrinsic = 1;
    2531         3355 :               break;
    2532         8948 :             case AB_OPTIONAL:
    2533         8948 :               attr->optional = 1;
    2534         8948 :               break;
    2535        43046 :             case AB_POINTER:
    2536        43046 :               attr->pointer = 1;
    2537        43046 :               break;
    2538          416 :             case AB_CLASS_POINTER:
    2539          416 :               attr->class_pointer = 1;
    2540          416 :               break;
    2541           62 :             case AB_PROTECTED:
    2542           62 :               attr->is_protected = 1;
    2543           62 :               break;
    2544        78692 :             case AB_VALUE:
    2545        78692 :               attr->value = 1;
    2546        78692 :               break;
    2547           15 :             case AB_VOLATILE:
    2548           15 :               attr->volatile_ = 1;
    2549           15 :               break;
    2550        26970 :             case AB_TARGET:
    2551        26970 :               attr->target = 1;
    2552        26970 :               break;
    2553           52 :             case AB_THREADPRIVATE:
    2554           52 :               attr->threadprivate = 1;
    2555           52 :               break;
    2556       406438 :             case AB_DUMMY:
    2557       406438 :               attr->dummy = 1;
    2558       406438 :               break;
    2559        33703 :             case AB_RESULT:
    2560        33703 :               attr->result = 1;
    2561        33703 :               break;
    2562           22 :             case AB_DATA:
    2563           22 :               attr->data = 1;
    2564           22 :               break;
    2565           83 :             case AB_IN_NAMELIST:
    2566           83 :               attr->in_namelist = 1;
    2567           83 :               break;
    2568          301 :             case AB_IN_COMMON:
    2569          301 :               attr->in_common = 1;
    2570          301 :               break;
    2571       180673 :             case AB_FUNCTION:
    2572       180673 :               attr->function = 1;
    2573       180673 :               break;
    2574        81923 :             case AB_SUBROUTINE:
    2575        81923 :               attr->subroutine = 1;
    2576        81923 :               break;
    2577        24037 :             case AB_GENERIC:
    2578        24037 :               attr->generic = 1;
    2579        24037 :               break;
    2580         2253 :             case AB_ABSTRACT:
    2581         2253 :               attr->abstract = 1;
    2582         2253 :               break;
    2583          137 :             case AB_SEQUENCE:
    2584          137 :               attr->sequence = 1;
    2585          137 :               break;
    2586        92617 :             case AB_ELEMENTAL:
    2587        92617 :               attr->elemental = 1;
    2588        92617 :               break;
    2589       117935 :             case AB_PURE:
    2590       117935 :               attr->pure = 1;
    2591       117935 :               break;
    2592         4158 :             case AB_IMPLICIT_PURE:
    2593         4158 :               attr->implicit_pure = 1;
    2594         4158 :               break;
    2595          311 :             case AB_UNLIMITED_POLY:
    2596          311 :               attr->unlimited_polymorphic = 1;
    2597          311 :               break;
    2598         2743 :             case AB_RECURSIVE:
    2599         2743 :               attr->recursive = 1;
    2600         2743 :               break;
    2601       154046 :             case AB_ALWAYS_EXPLICIT:
    2602       154046 :               attr->always_explicit = 1;
    2603       154046 :               break;
    2604           13 :             case AB_CRAY_POINTER:
    2605           13 :               attr->cray_pointer = 1;
    2606           13 :               break;
    2607           13 :             case AB_CRAY_POINTEE:
    2608           13 :               attr->cray_pointee = 1;
    2609           13 :               break;
    2610        39911 :             case AB_IS_BIND_C:
    2611        39911 :               attr->is_bind_c = 1;
    2612        39911 :               break;
    2613        68824 :             case AB_IS_C_INTEROP:
    2614        68824 :               attr->is_c_interop = 1;
    2615        68824 :               break;
    2616        24897 :             case AB_IS_ISO_C:
    2617        24897 :               attr->is_iso_c = 1;
    2618        24897 :               break;
    2619         2606 :             case AB_ALLOC_COMP:
    2620         2606 :               attr->alloc_comp = 1;
    2621         2606 :               break;
    2622           22 :             case AB_COARRAY_COMP:
    2623           22 :               attr->coarray_comp = 1;
    2624           22 :               break;
    2625            4 :             case AB_LOCK_COMP:
    2626            4 :               attr->lock_comp = 1;
    2627            4 :               break;
    2628            0 :             case AB_EVENT_COMP:
    2629            0 :               attr->event_comp = 1;
    2630            0 :               break;
    2631          876 :             case AB_POINTER_COMP:
    2632          876 :               attr->pointer_comp = 1;
    2633          876 :               break;
    2634          247 :             case AB_PROC_POINTER_COMP:
    2635          247 :               attr->proc_pointer_comp = 1;
    2636          247 :               break;
    2637        19963 :             case AB_PRIVATE_COMP:
    2638        19963 :               attr->private_comp = 1;
    2639        19963 :               break;
    2640         1791 :             case AB_ZERO_COMP:
    2641         1791 :               attr->zero_comp = 1;
    2642         1791 :               break;
    2643         4053 :             case AB_IS_CLASS:
    2644         4053 :               attr->is_class = 1;
    2645         4053 :               break;
    2646         4963 :             case AB_PROCEDURE:
    2647         4963 :               attr->procedure = 1;
    2648         4963 :               break;
    2649        48866 :             case AB_PROC_POINTER:
    2650        48866 :               attr->proc_pointer = 1;
    2651        48866 :               break;
    2652        14744 :             case AB_VTYPE:
    2653        14744 :               attr->vtype = 1;
    2654        14744 :               break;
    2655        14434 :             case AB_VTAB:
    2656        14434 :               attr->vtab = 1;
    2657        14434 :               break;
    2658          444 :             case AB_OMP_DECLARE_TARGET:
    2659          444 :               attr->omp_declare_target = 1;
    2660          444 :               break;
    2661           10 :             case AB_OMP_DECLARE_TARGET_LINK:
    2662           10 :               attr->omp_declare_target_link = 1;
    2663           10 :               break;
    2664            0 :             case AB_OMP_DECLARE_TARGET_LOCAL:
    2665            0 :               attr->omp_declare_target_local = 1;
    2666            0 :               break;
    2667            0 :             case AB_OMP_GROUPPRIVATE:
    2668            0 :               attr->omp_groupprivate = 1;
    2669            0 :               break;
    2670       196452 :             case AB_ARRAY_OUTER_DEPENDENCY:
    2671       196452 :               attr->array_outer_dependency =1;
    2672       196452 :               break;
    2673         1021 :             case AB_MODULE_PROCEDURE:
    2674         1021 :               attr->module_procedure =1;
    2675         1021 :               break;
    2676          110 :             case AB_OACC_DECLARE_CREATE:
    2677          110 :               attr->oacc_declare_create = 1;
    2678          110 :               break;
    2679            2 :             case AB_OACC_DECLARE_COPYIN:
    2680            2 :               attr->oacc_declare_copyin = 1;
    2681            2 :               break;
    2682            0 :             case AB_OACC_DECLARE_DEVICEPTR:
    2683            0 :               attr->oacc_declare_deviceptr = 1;
    2684            0 :               break;
    2685           34 :             case AB_OACC_DECLARE_DEVICE_RESIDENT:
    2686           34 :               attr->oacc_declare_device_resident = 1;
    2687           34 :               break;
    2688            2 :             case AB_OACC_DECLARE_LINK:
    2689            2 :               attr->oacc_declare_link = 1;
    2690            2 :               break;
    2691          423 :             case AB_PDT_KIND:
    2692          423 :               attr->pdt_kind = 1;
    2693          423 :               break;
    2694          385 :             case AB_PDT_LEN:
    2695          385 :               attr->pdt_len = 1;
    2696          385 :               break;
    2697          240 :             case AB_PDT_TYPE:
    2698          240 :               attr->pdt_type = 1;
    2699          240 :               break;
    2700           16 :             case AB_PDT_COMP:
    2701           16 :               attr->pdt_comp = 1;
    2702           16 :               break;
    2703          207 :             case AB_PDT_TEMPLATE:
    2704          207 :               attr->pdt_template = 1;
    2705          207 :               break;
    2706           65 :             case AB_PDT_ARRAY:
    2707           65 :               attr->pdt_array = 1;
    2708           65 :               break;
    2709            0 :             case AB_PDT_STRING:
    2710            0 :               attr->pdt_string = 1;
    2711            0 :               break;
    2712            8 :             case AB_OACC_ROUTINE_LOP_GANG:
    2713            8 :               verify_OACC_ROUTINE_LOP_NONE (attr->oacc_routine_lop);
    2714            8 :               attr->oacc_routine_lop = OACC_ROUTINE_LOP_GANG;
    2715            8 :               break;
    2716            8 :             case AB_OACC_ROUTINE_LOP_WORKER:
    2717            8 :               verify_OACC_ROUTINE_LOP_NONE (attr->oacc_routine_lop);
    2718            8 :               attr->oacc_routine_lop = OACC_ROUTINE_LOP_WORKER;
    2719            8 :               break;
    2720            8 :             case AB_OACC_ROUTINE_LOP_VECTOR:
    2721            8 :               verify_OACC_ROUTINE_LOP_NONE (attr->oacc_routine_lop);
    2722            8 :               attr->oacc_routine_lop = OACC_ROUTINE_LOP_VECTOR;
    2723            8 :               break;
    2724           72 :             case AB_OACC_ROUTINE_LOP_SEQ:
    2725           72 :               verify_OACC_ROUTINE_LOP_NONE (attr->oacc_routine_lop);
    2726           72 :               attr->oacc_routine_lop = OACC_ROUTINE_LOP_SEQ;
    2727           72 :               break;
    2728           20 :             case AB_OACC_ROUTINE_NOHOST:
    2729           20 :               attr->oacc_routine_nohost = 1;
    2730           20 :               break;
    2731           24 :             case AB_OMP_REQ_REVERSE_OFFLOAD:
    2732           24 :               gfc_omp_requires_add_clause (OMP_REQ_REVERSE_OFFLOAD,
    2733              :                                            "reverse_offload",
    2734              :                                            &gfc_current_locus,
    2735              :                                            module_name);
    2736           24 :               break;
    2737            0 :             case AB_OMP_REQ_UNIFIED_ADDRESS:
    2738            0 :               gfc_omp_requires_add_clause (OMP_REQ_UNIFIED_ADDRESS,
    2739              :                                            "unified_address",
    2740              :                                            &gfc_current_locus,
    2741              :                                            module_name);
    2742            0 :               break;
    2743            0 :             case AB_OMP_REQ_UNIFIED_SHARED_MEMORY:
    2744            0 :               gfc_omp_requires_add_clause (OMP_REQ_UNIFIED_SHARED_MEMORY,
    2745              :                                            "unified_shared_memory",
    2746              :                                            &gfc_current_locus,
    2747              :                                            module_name);
    2748            0 :               break;
    2749            1 :             case AB_OMP_REQ_SELF_MAPS:
    2750            1 :               gfc_omp_requires_add_clause (OMP_REQ_SELF_MAPS,
    2751              :                                            "self_maps",
    2752              :                                            &gfc_current_locus,
    2753              :                                            module_name);
    2754            1 :               break;
    2755            0 :             case AB_OMP_REQ_DYNAMIC_ALLOCATORS:
    2756            0 :               gfc_omp_requires_add_clause (OMP_REQ_DYNAMIC_ALLOCATORS,
    2757              :                                            "dynamic_allocators",
    2758              :                                            &gfc_current_locus,
    2759              :                                            module_name);
    2760            0 :               break;
    2761            2 :             case AB_OMP_REQ_MEM_ORDER_SEQ_CST:
    2762            2 :               gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST,
    2763              :                                            "seq_cst", &gfc_current_locus,
    2764              :                                            module_name);
    2765            2 :               break;
    2766            2 :             case AB_OMP_REQ_MEM_ORDER_ACQ_REL:
    2767            2 :               gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL,
    2768              :                                            "acq_rel", &gfc_current_locus,
    2769              :                                            module_name);
    2770            2 :               break;
    2771            0 :             case AB_OMP_REQ_MEM_ORDER_ACQUIRE:
    2772            0 :               gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE,
    2773              :                                            "acquires", &gfc_current_locus,
    2774              :                                            module_name);
    2775            0 :               break;
    2776            2 :             case AB_OMP_REQ_MEM_ORDER_RELAXED:
    2777            2 :               gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_RELAXED,
    2778              :                                            "relaxed", &gfc_current_locus,
    2779              :                                            module_name);
    2780            2 :               break;
    2781            0 :             case AB_OMP_REQ_MEM_ORDER_RELEASE:
    2782            0 :               gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_RELEASE,
    2783              :                                            "release", &gfc_current_locus,
    2784              :                                            module_name);
    2785            0 :               break;
    2786            8 :             case AB_OMP_DEVICE_TYPE_HOST:
    2787            8 :               attr->omp_device_type = OMP_DEVICE_TYPE_HOST;
    2788            8 :               break;
    2789            5 :             case AB_OMP_DEVICE_TYPE_NOHOST:
    2790            5 :               attr->omp_device_type = OMP_DEVICE_TYPE_NOHOST;
    2791            5 :               break;
    2792          297 :             case AB_OMP_DEVICE_TYPE_ANY:
    2793          297 :               attr->omp_device_type = OMP_DEVICE_TYPE_ANY;
    2794          297 :               break;
    2795              :             }
    2796              :         }
    2797              :     }
    2798      1482074 : }
    2799              : 
    2800              : 
    2801              : static const mstring bt_types[] = {
    2802              :     minit ("INTEGER", BT_INTEGER),
    2803              :     minit ("REAL", BT_REAL),
    2804              :     minit ("COMPLEX", BT_COMPLEX),
    2805              :     minit ("LOGICAL", BT_LOGICAL),
    2806              :     minit ("CHARACTER", BT_CHARACTER),
    2807              :     minit ("UNION", BT_UNION),
    2808              :     minit ("DERIVED", BT_DERIVED),
    2809              :     minit ("CLASS", BT_CLASS),
    2810              :     minit ("PROCEDURE", BT_PROCEDURE),
    2811              :     minit ("UNKNOWN", BT_UNKNOWN),
    2812              :     minit ("VOID", BT_VOID),
    2813              :     minit ("ASSUMED", BT_ASSUMED),
    2814              :     minit ("UNSIGNED", BT_UNSIGNED),
    2815              :     minit (NULL, -1)
    2816              : };
    2817              : 
    2818              : 
    2819              : static void
    2820        40976 : mio_charlen (gfc_charlen **clp)
    2821              : {
    2822        40976 :   gfc_charlen *cl;
    2823              : 
    2824        40976 :   mio_lparen ();
    2825              : 
    2826        40976 :   if (iomode == IO_OUTPUT)
    2827              :     {
    2828        19322 :       cl = *clp;
    2829        19322 :       if (cl != NULL)
    2830        18563 :         mio_expr (&cl->length);
    2831              :     }
    2832              :   else
    2833              :     {
    2834        21654 :       if (peek_atom () != ATOM_RPAREN)
    2835              :         {
    2836        21195 :           cl = gfc_new_charlen (gfc_current_ns, NULL);
    2837        21195 :           mio_expr (&cl->length);
    2838        21195 :           *clp = cl;
    2839              :         }
    2840              :     }
    2841              : 
    2842        40976 :   mio_rparen ();
    2843        40976 : }
    2844              : 
    2845              : 
    2846              : /* See if a name is a generated name.  */
    2847              : 
    2848              : static int
    2849       724309 : check_unique_name (const char *name)
    2850              : {
    2851       724309 :   return *name == '@';
    2852              : }
    2853              : 
    2854              : 
    2855              : static void
    2856      1893276 : mio_typespec (gfc_typespec *ts)
    2857              : {
    2858      1893276 :   mio_lparen ();
    2859              : 
    2860      1893276 :   ts->type = MIO_NAME (bt) (ts->type, bt_types);
    2861              : 
    2862      1893276 :   if (!gfc_bt_struct (ts->type) && ts->type != BT_CLASS)
    2863      1595834 :     mio_integer (&ts->kind);
    2864              :   else
    2865       297442 :     mio_symbol_ref (&ts->u.derived);
    2866              : 
    2867      1893276 :   mio_symbol_ref (&ts->interface);
    2868              : 
    2869              :   /* Add info for C interop and is_iso_c.  */
    2870      1893276 :   mio_integer (&ts->is_c_interop);
    2871      1893276 :   mio_integer (&ts->is_iso_c);
    2872              : 
    2873              :   /* If the typespec is for an identifier either from iso_c_binding, or
    2874              :      a constant that was initialized to an identifier from it, use the
    2875              :      f90_type.  Otherwise, use the ts->type, since it shouldn't matter.  */
    2876      1893276 :   if (ts->is_iso_c)
    2877       118132 :     ts->f90_type = MIO_NAME (bt) (ts->f90_type, bt_types);
    2878              :   else
    2879      1775144 :     ts->f90_type = MIO_NAME (bt) (ts->type, bt_types);
    2880              : 
    2881      1893276 :   if (ts->type != BT_CHARACTER)
    2882              :     {
    2883              :       /* ts->u.cl is only valid for BT_CHARACTER.  */
    2884      1852306 :       mio_lparen ();
    2885      1852306 :       mio_rparen ();
    2886              :     }
    2887              :   else
    2888        40970 :     mio_charlen (&ts->u.cl);
    2889              : 
    2890              :   /* So as not to disturb the existing API, use an ATOM_NAME to
    2891              :      transmit deferred characteristic for characters (F2003).  */
    2892      1893276 :   if (iomode == IO_OUTPUT)
    2893              :     {
    2894       432791 :       if (ts->type == BT_CHARACTER && ts->deferred)
    2895          715 :         write_atom (ATOM_NAME, "DEFERRED_CL");
    2896              :     }
    2897      1460485 :   else if (peek_atom () != ATOM_RPAREN)
    2898              :     {
    2899         4770 :       if (parse_atom () != ATOM_NAME)
    2900            0 :         bad_module ("Expected string");
    2901         4770 :       ts->deferred = 1;
    2902              :     }
    2903              : 
    2904      1893276 :   mio_rparen ();
    2905      1893276 : }
    2906              : 
    2907              : 
    2908              : static const mstring array_spec_types[] = {
    2909              :     minit ("EXPLICIT", AS_EXPLICIT),
    2910              :     minit ("ASSUMED_RANK", AS_ASSUMED_RANK),
    2911              :     minit ("ASSUMED_SHAPE", AS_ASSUMED_SHAPE),
    2912              :     minit ("DEFERRED", AS_DEFERRED),
    2913              :     minit ("ASSUMED_SIZE", AS_ASSUMED_SIZE),
    2914              :     minit (NULL, -1)
    2915              : };
    2916              : 
    2917              : 
    2918              : static void
    2919      1482054 : mio_array_spec (gfc_array_spec **asp)
    2920              : {
    2921      1482054 :   gfc_array_spec *as;
    2922      1482054 :   int i;
    2923              : 
    2924      1482054 :   mio_lparen ();
    2925              : 
    2926      1482054 :   if (iomode == IO_OUTPUT)
    2927              :     {
    2928       334084 :       int rank;
    2929              : 
    2930       334084 :       if (*asp == NULL)
    2931       315977 :         goto done;
    2932        18107 :       as = *asp;
    2933              : 
    2934              :       /* mio_integer expects nonnegative values.  */
    2935        18107 :       rank = as->rank > 0 ? as->rank : 0;
    2936        18107 :       mio_integer (&rank);
    2937              :     }
    2938              :   else
    2939              :     {
    2940      1147970 :       if (peek_atom () == ATOM_RPAREN)
    2941              :         {
    2942      1085674 :           *asp = NULL;
    2943      1085674 :           goto done;
    2944              :         }
    2945              : 
    2946        62296 :       *asp = as = gfc_get_array_spec ();
    2947        62296 :       mio_integer (&as->rank);
    2948              :     }
    2949              : 
    2950        80403 :   mio_integer (&as->corank);
    2951        80403 :   as->type = MIO_NAME (array_type) (as->type, array_spec_types);
    2952              : 
    2953        80403 :   if (iomode == IO_INPUT && as->type == AS_ASSUMED_RANK)
    2954        23620 :     as->rank = -1;
    2955        80403 :   if (iomode == IO_INPUT && as->corank)
    2956          148 :     as->cotype = (as->type == AS_DEFERRED) ? AS_DEFERRED : AS_EXPLICIT;
    2957              : 
    2958        80403 :   if (as->rank + as->corank > 0)
    2959       111232 :     for (i = 0; i < as->rank + as->corank; i++)
    2960              :       {
    2961        58356 :         mio_expr (&as->lower[i]);
    2962        58356 :         mio_expr (&as->upper[i]);
    2963              :       }
    2964              : 
    2965        27527 : done:
    2966      1482054 :   mio_rparen ();
    2967      1482054 : }
    2968              : 
    2969              : 
    2970              : /* Given a pointer to an array reference structure (which lives in a
    2971              :    gfc_ref structure), find the corresponding array specification
    2972              :    structure.  Storing the pointer in the ref structure doesn't quite
    2973              :    work when loading from a module. Generating code for an array
    2974              :    reference also needs more information than just the array spec.  */
    2975              : 
    2976              : static const mstring array_ref_types[] = {
    2977              :     minit ("FULL", AR_FULL),
    2978              :     minit ("ELEMENT", AR_ELEMENT),
    2979              :     minit ("SECTION", AR_SECTION),
    2980              :     minit (NULL, -1)
    2981              : };
    2982              : 
    2983              : 
    2984              : static void
    2985         1767 : mio_array_ref (gfc_array_ref *ar)
    2986              : {
    2987         1767 :   int i;
    2988              : 
    2989         1767 :   mio_lparen ();
    2990         1767 :   ar->type = MIO_NAME (ar_type) (ar->type, array_ref_types);
    2991         1767 :   mio_integer (&ar->dimen);
    2992              : 
    2993         1767 :   switch (ar->type)
    2994              :     {
    2995              :     case AR_FULL:
    2996              :       break;
    2997              : 
    2998              :     case AR_ELEMENT:
    2999          982 :       for (i = 0; i < ar->dimen; i++)
    3000          505 :         mio_expr (&ar->start[i]);
    3001              : 
    3002              :       break;
    3003              : 
    3004              :     case AR_SECTION:
    3005            0 :       for (i = 0; i < ar->dimen; i++)
    3006              :         {
    3007            0 :           mio_expr (&ar->start[i]);
    3008            0 :           mio_expr (&ar->end[i]);
    3009            0 :           mio_expr (&ar->stride[i]);
    3010              :         }
    3011              : 
    3012              :       break;
    3013              : 
    3014            0 :     case AR_UNKNOWN:
    3015            0 :       gfc_internal_error ("mio_array_ref(): Unknown array ref");
    3016              :     }
    3017              : 
    3018              :   /* Unfortunately, ar->dimen_type is an anonymous enumerated type so
    3019              :      we can't call mio_integer directly.  Instead loop over each element
    3020              :      and cast it to/from an integer.  */
    3021         1767 :   if (iomode == IO_OUTPUT)
    3022              :     {
    3023         1990 :       for (i = 0; i < ar->dimen; i++)
    3024              :         {
    3025         1112 :           HOST_WIDE_INT tmp = (HOST_WIDE_INT)ar->dimen_type[i];
    3026         1112 :           write_atom (ATOM_INTEGER, &tmp);
    3027              :         }
    3028              :     }
    3029              :   else
    3030              :     {
    3031         2044 :       for (i = 0; i < ar->dimen; i++)
    3032              :         {
    3033         1155 :           require_atom (ATOM_INTEGER);
    3034         1155 :           ar->dimen_type[i] = (enum gfc_array_ref_dimen_type) atom_int;
    3035              :         }
    3036              :     }
    3037              : 
    3038         1767 :   if (iomode == IO_INPUT)
    3039              :     {
    3040          889 :       ar->where = gfc_current_locus;
    3041              : 
    3042         2044 :       for (i = 0; i < ar->dimen; i++)
    3043         1155 :         ar->c_where[i] = gfc_current_locus;
    3044              :     }
    3045              : 
    3046         1767 :   mio_rparen ();
    3047         1767 : }
    3048              : 
    3049              : 
    3050              : /* Saves or restores a pointer.  The pointer is converted back and
    3051              :    forth from an integer.  We return the pointer_info pointer so that
    3052              :    the caller can take additional action based on the pointer type.  */
    3053              : 
    3054              : static pointer_info *
    3055      6787558 : mio_pointer_ref (void *gp)
    3056              : {
    3057      6787558 :   pointer_info *p;
    3058              : 
    3059      6787558 :   if (iomode == IO_OUTPUT)
    3060              :     {
    3061      1576402 :       p = get_pointer (*((char **) gp));
    3062      1576402 :       HOST_WIDE_INT hwi = p->integer;
    3063      1576402 :       write_atom (ATOM_INTEGER, &hwi);
    3064              :     }
    3065              :   else
    3066              :     {
    3067      5211156 :       require_atom (ATOM_INTEGER);
    3068      5211156 :       p = add_fixup (atom_int, gp);
    3069              :     }
    3070              : 
    3071      6787558 :   return p;
    3072              : }
    3073              : 
    3074              : 
    3075              : /* Save and load references to components that occur within
    3076              :    expressions.  We have to describe these references by a number and
    3077              :    by name.  The number is necessary for forward references during
    3078              :    reading, and the name is necessary if the symbol already exists in
    3079              :    the namespace and is not loaded again.  */
    3080              : 
    3081              : static void
    3082          730 : mio_component_ref (gfc_component **cp)
    3083              : {
    3084          730 :   pointer_info *p;
    3085              : 
    3086          730 :   p = mio_pointer_ref (cp);
    3087          730 :   if (p->type == P_UNKNOWN)
    3088          150 :     p->type = P_COMPONENT;
    3089          730 : }
    3090              : 
    3091              : 
    3092              : static void mio_namespace_ref (gfc_namespace **nsp);
    3093              : static void mio_formal_arglist (gfc_formal_arglist **formal);
    3094              : static void mio_typebound_proc (gfc_typebound_proc** proc);
    3095              : static void mio_actual_arglist (gfc_actual_arglist **ap, bool pdt);
    3096              : 
    3097              : static void
    3098       255021 : mio_component (gfc_component *c, int vtype)
    3099              : {
    3100       255021 :   pointer_info *p;
    3101              : 
    3102       255021 :   mio_lparen ();
    3103              : 
    3104       255021 :   if (iomode == IO_OUTPUT)
    3105              :     {
    3106       100516 :       p = get_pointer (c);
    3107       100516 :       mio_hwi (&p->integer);
    3108              :     }
    3109              :   else
    3110              :     {
    3111       154505 :       HOST_WIDE_INT n;
    3112       154505 :       mio_hwi (&n);
    3113       154505 :       p = get_integer (n);
    3114       154505 :       associate_integer_pointer (p, c);
    3115              :     }
    3116              : 
    3117       255021 :   if (p->type == P_UNKNOWN)
    3118       254898 :     p->type = P_COMPONENT;
    3119              : 
    3120       255021 :   mio_pool_string (&c->name);
    3121       255021 :   mio_typespec (&c->ts);
    3122       255021 :   mio_array_spec (&c->as);
    3123              : 
    3124              :   /* PDT templates store the expression for the kind of a component here.  */
    3125       255021 :   mio_expr (&c->kind_expr);
    3126              : 
    3127              :   /* PDT types store the component specification list here. */
    3128       255021 :   mio_actual_arglist (&c->param_list, true);
    3129              : 
    3130       255021 :   mio_symbol_attribute (&c->attr);
    3131       255021 :   if (c->ts.type == BT_CLASS)
    3132         2095 :     c->attr.class_ok = 1;
    3133       255021 :   c->attr.access = MIO_NAME (gfc_access) (c->attr.access, access_types);
    3134              : 
    3135       255021 :   if (!vtype || strcmp (c->name, "_final") == 0
    3136       159026 :       || strcmp (c->name, "_hash") == 0)
    3137       121000 :     mio_expr (&c->initializer);
    3138              : 
    3139       255021 :   if (c->attr.proc_pointer)
    3140        84456 :     mio_typebound_proc (&c->tb);
    3141              : 
    3142       255021 :   c->loc = gfc_current_locus;
    3143              : 
    3144       255021 :   mio_rparen ();
    3145       255021 : }
    3146              : 
    3147              : 
    3148              : static void
    3149      1227033 : mio_component_list (gfc_component **cp, int vtype)
    3150              : {
    3151      1227033 :   gfc_component *c, *tail;
    3152              : 
    3153      1227033 :   mio_lparen ();
    3154              : 
    3155      1227033 :   if (iomode == IO_OUTPUT)
    3156              :     {
    3157       334084 :       for (c = *cp; c; c = c->next)
    3158       100516 :         mio_component (c, vtype);
    3159              :     }
    3160              :   else
    3161              :     {
    3162       993465 :       *cp = NULL;
    3163       993465 :       tail = NULL;
    3164              : 
    3165      1147970 :       for (;;)
    3166              :         {
    3167      1147970 :           if (peek_atom () == ATOM_RPAREN)
    3168              :             break;
    3169              : 
    3170       154505 :           c = gfc_get_component ();
    3171       154505 :           mio_component (c, vtype);
    3172              : 
    3173       154505 :           if (tail == NULL)
    3174        48498 :             *cp = c;
    3175              :           else
    3176       106007 :             tail->next = c;
    3177              : 
    3178              :           tail = c;
    3179              :         }
    3180              :     }
    3181              : 
    3182      1227033 :   mio_rparen ();
    3183      1227033 : }
    3184              : 
    3185              : 
    3186              : static void
    3187         7067 : mio_actual_arg (gfc_actual_arglist *a, bool pdt)
    3188              : {
    3189         7067 :   mio_lparen ();
    3190         7067 :   mio_pool_string (&a->name);
    3191         7067 :   mio_expr (&a->expr);
    3192         7067 :   if (pdt)
    3193         1302 :     mio_integer ((int *)&a->spec_type);
    3194         7067 :   mio_rparen ();
    3195         7067 : }
    3196              : 
    3197              : 
    3198              : static void
    3199      1895751 : mio_actual_arglist (gfc_actual_arglist **ap, bool pdt)
    3200              : {
    3201      1895751 :   gfc_actual_arglist *a, *tail;
    3202              : 
    3203      1895751 :   mio_lparen ();
    3204              : 
    3205      1895751 :   if (iomode == IO_OUTPUT)
    3206              :     {
    3207       437681 :       for (a = *ap; a; a = a->next)
    3208         3614 :         mio_actual_arg (a, pdt);
    3209              : 
    3210              :     }
    3211              :   else
    3212              :     {
    3213              :       tail = NULL;
    3214              : 
    3215      1468590 :       for (;;)
    3216              :         {
    3217      1465137 :           if (peek_atom () != ATOM_LPAREN)
    3218              :             break;
    3219              : 
    3220         3453 :           a = gfc_get_actual_arglist ();
    3221              : 
    3222         3453 :           if (tail == NULL)
    3223         1747 :             *ap = a;
    3224              :           else
    3225         1706 :             tail->next = a;
    3226              : 
    3227         3453 :           tail = a;
    3228         3453 :           mio_actual_arg (a, pdt);
    3229              :         }
    3230              :     }
    3231              : 
    3232      1895751 :   mio_rparen ();
    3233      1895751 : }
    3234              : 
    3235              : 
    3236              : /* Read and write formal argument lists.  */
    3237              : 
    3238              : static void
    3239      1227033 : mio_formal_arglist (gfc_formal_arglist **formal)
    3240              : {
    3241      1227033 :   gfc_formal_arglist *f, *tail;
    3242              : 
    3243      1227033 :   mio_lparen ();
    3244              : 
    3245      1227033 :   if (iomode == IO_OUTPUT)
    3246              :     {
    3247       312256 :       for (f = *formal; f; f = f->next)
    3248        78688 :         mio_symbol_ref (&f->sym);
    3249              :     }
    3250              :   else
    3251              :     {
    3252       993465 :       *formal = tail = NULL;
    3253              : 
    3254      1400001 :       while (peek_atom () != ATOM_RPAREN)
    3255              :         {
    3256       406536 :           f = gfc_get_formal_arglist ();
    3257       406536 :           mio_symbol_ref (&f->sym);
    3258              : 
    3259       406536 :           if (*formal == NULL)
    3260       214539 :             *formal = f;
    3261              :           else
    3262       191997 :             tail->next = f;
    3263              : 
    3264              :           tail = f;
    3265              :         }
    3266              :     }
    3267              : 
    3268      1227033 :   mio_rparen ();
    3269      1227033 : }
    3270              : 
    3271              : 
    3272              : /* Save or restore a reference to a symbol node.  */
    3273              : 
    3274              : pointer_info *
    3275      5326227 : mio_symbol_ref (gfc_symbol **symp)
    3276              : {
    3277      5326227 :   pointer_info *p;
    3278              : 
    3279      5326227 :   p = mio_pointer_ref (symp);
    3280      5326227 :   if (p->type == P_UNKNOWN)
    3281       134082 :     p->type = P_SYMBOL;
    3282              : 
    3283      5326227 :   if (iomode == IO_OUTPUT)
    3284              :     {
    3285      1108831 :       if (p->u.wsym.state == UNREFERENCED)
    3286       150796 :         p->u.wsym.state = NEEDS_WRITE;
    3287              :     }
    3288              :   else
    3289              :     {
    3290      4217396 :       if (p->u.rsym.state == UNUSED)
    3291       609040 :         p->u.rsym.state = NEEDED;
    3292              :     }
    3293      5326227 :   return p;
    3294              : }
    3295              : 
    3296              : 
    3297              : /* Save or restore a reference to a symtree node.  */
    3298              : 
    3299              : static void
    3300        27492 : mio_symtree_ref (gfc_symtree **stp)
    3301              : {
    3302        27492 :   pointer_info *p;
    3303        27492 :   fixup_t *f;
    3304              : 
    3305        27492 :   if (iomode == IO_OUTPUT)
    3306        14405 :     mio_symbol_ref (&(*stp)->n.sym);
    3307              :   else
    3308              :     {
    3309        13087 :       require_atom (ATOM_INTEGER);
    3310        13087 :       p = get_integer (atom_int);
    3311              : 
    3312              :       /* An unused equivalence member; make a symbol and a symtree
    3313              :          for it.  */
    3314        13087 :       if (in_load_equiv && p->u.rsym.symtree == NULL)
    3315              :         {
    3316              :           /* Since this is not used, it must have a unique name.  */
    3317           87 :           p->u.rsym.symtree = gfc_get_unique_symtree (gfc_current_ns);
    3318              : 
    3319              :           /* Make the symbol.  */
    3320           87 :           if (p->u.rsym.sym == NULL)
    3321              :             {
    3322           75 :               p->u.rsym.sym = gfc_new_symbol (p->u.rsym.true_name,
    3323              :                                               gfc_current_ns);
    3324           75 :               p->u.rsym.sym->module = gfc_get_string ("%s", p->u.rsym.module);
    3325              :             }
    3326              : 
    3327           87 :           p->u.rsym.symtree->n.sym = p->u.rsym.sym;
    3328           87 :           p->u.rsym.symtree->n.sym->refs++;
    3329           87 :           p->u.rsym.referenced = 1;
    3330              : 
    3331              :           /* If the symbol is PRIVATE and in COMMON, load_commons will
    3332              :              generate a fixup symbol, which must be associated.  */
    3333           87 :           if (p->fixup)
    3334            2 :             resolve_fixups (p->fixup, p->u.rsym.sym);
    3335           87 :           p->fixup = NULL;
    3336              :         }
    3337              : 
    3338        13087 :       if (p->type == P_UNKNOWN)
    3339            0 :         p->type = P_SYMBOL;
    3340              : 
    3341        13087 :       if (p->u.rsym.state == UNUSED)
    3342         2512 :         p->u.rsym.state = NEEDED;
    3343              : 
    3344        13087 :       if (p->u.rsym.symtree != NULL)
    3345              :         {
    3346         3529 :           *stp = p->u.rsym.symtree;
    3347              :         }
    3348              :       else
    3349              :         {
    3350         9558 :           f = XCNEW (fixup_t);
    3351              : 
    3352         9558 :           f->next = p->u.rsym.stfixup;
    3353         9558 :           p->u.rsym.stfixup = f;
    3354              : 
    3355         9558 :           f->pointer = (void **) stp;
    3356              :         }
    3357              :     }
    3358        27492 : }
    3359              : 
    3360              : 
    3361              : static void
    3362        34146 : mio_iterator (gfc_iterator **ip)
    3363              : {
    3364        34146 :   gfc_iterator *iter;
    3365              : 
    3366        34146 :   mio_lparen ();
    3367              : 
    3368        34146 :   if (iomode == IO_OUTPUT)
    3369              :     {
    3370         9451 :       if (*ip == NULL)
    3371         9445 :         goto done;
    3372              :     }
    3373              :   else
    3374              :     {
    3375        24695 :       if (peek_atom () == ATOM_RPAREN)
    3376              :         {
    3377        24689 :           *ip = NULL;
    3378        24689 :           goto done;
    3379              :         }
    3380              : 
    3381            6 :       *ip = gfc_get_iterator ();
    3382              :     }
    3383              : 
    3384           12 :   iter = *ip;
    3385              : 
    3386           12 :   mio_expr (&iter->var);
    3387           12 :   mio_expr (&iter->start);
    3388           12 :   mio_expr (&iter->end);
    3389           12 :   mio_expr (&iter->step);
    3390              : 
    3391        34146 : done:
    3392        34146 :   mio_rparen ();
    3393        34146 : }
    3394              : 
    3395              : 
    3396              : static void
    3397        21001 : mio_constructor (gfc_constructor_base *cp)
    3398              : {
    3399        21001 :   gfc_constructor *c;
    3400              : 
    3401        21001 :   mio_lparen ();
    3402              : 
    3403        21001 :   if (iomode == IO_OUTPUT)
    3404              :     {
    3405        13457 :       for (c = gfc_constructor_first (*cp); c; c = gfc_constructor_next (c))
    3406              :         {
    3407         9451 :           mio_lparen ();
    3408         9451 :           mio_expr (&c->expr);
    3409         9451 :           mio_iterator (&c->iterator);
    3410         9451 :           mio_rparen ();
    3411              :         }
    3412              :     }
    3413              :   else
    3414              :     {
    3415        41690 :       while (peek_atom () != ATOM_RPAREN)
    3416              :         {
    3417        24695 :           c = gfc_constructor_append_expr (cp, NULL, NULL);
    3418              : 
    3419        24695 :           mio_lparen ();
    3420        24695 :           mio_expr (&c->expr);
    3421        24695 :           mio_iterator (&c->iterator);
    3422        24695 :           mio_rparen ();
    3423              :         }
    3424              :     }
    3425              : 
    3426        21001 :   mio_rparen ();
    3427        21001 : }
    3428              : 
    3429              : 
    3430              : static const mstring ref_types[] = {
    3431              :     minit ("ARRAY", REF_ARRAY),
    3432              :     minit ("COMPONENT", REF_COMPONENT),
    3433              :     minit ("SUBSTRING", REF_SUBSTRING),
    3434              :     minit ("INQUIRY", REF_INQUIRY),
    3435              :     minit (NULL, -1)
    3436              : };
    3437              : 
    3438              : static const mstring inquiry_types[] = {
    3439              :     minit ("RE", INQUIRY_RE),
    3440              :     minit ("IM", INQUIRY_IM),
    3441              :     minit ("KIND", INQUIRY_KIND),
    3442              :     minit ("LEN", INQUIRY_LEN),
    3443              :     minit (NULL, -1)
    3444              : };
    3445              : 
    3446              : 
    3447              : static void
    3448         2503 : mio_ref (gfc_ref **rp)
    3449              : {
    3450         2503 :   gfc_ref *r;
    3451              : 
    3452         2503 :   mio_lparen ();
    3453              : 
    3454         2503 :   r = *rp;
    3455         2503 :   r->type = MIO_NAME (ref_type) (r->type, ref_types);
    3456              : 
    3457         2503 :   switch (r->type)
    3458              :     {
    3459         1767 :     case REF_ARRAY:
    3460         1767 :       mio_array_ref (&r->u.ar);
    3461         1767 :       break;
    3462              : 
    3463          730 :     case REF_COMPONENT:
    3464          730 :       mio_symbol_ref (&r->u.c.sym);
    3465          730 :       mio_component_ref (&r->u.c.component);
    3466          730 :       break;
    3467              : 
    3468            6 :     case REF_SUBSTRING:
    3469            6 :       mio_expr (&r->u.ss.start);
    3470            6 :       mio_expr (&r->u.ss.end);
    3471            6 :       mio_charlen (&r->u.ss.length);
    3472            6 :       break;
    3473              : 
    3474            0 :     case REF_INQUIRY:
    3475            0 :       r->u.i = MIO_NAME (inquiry_type) (r->u.i, inquiry_types);
    3476            0 :       break;
    3477              :     }
    3478              : 
    3479         2503 :   mio_rparen ();
    3480         2503 : }
    3481              : 
    3482              : 
    3483              : static void
    3484        14209 : mio_ref_list (gfc_ref **rp)
    3485              : {
    3486        14209 :   gfc_ref *ref, *head, *tail;
    3487              : 
    3488        14209 :   mio_lparen ();
    3489              : 
    3490        14209 :   if (iomode == IO_OUTPUT)
    3491              :     {
    3492         8710 :       for (ref = *rp; ref; ref = ref->next)
    3493         1317 :         mio_ref (&ref);
    3494              :     }
    3495              :   else
    3496              :     {
    3497         6816 :       head = tail = NULL;
    3498              : 
    3499         8002 :       while (peek_atom () != ATOM_RPAREN)
    3500              :         {
    3501         1186 :           if (head == NULL)
    3502         1049 :             head = tail = gfc_get_ref ();
    3503              :           else
    3504              :             {
    3505          137 :               tail->next = gfc_get_ref ();
    3506          137 :               tail = tail->next;
    3507              :             }
    3508              : 
    3509         1186 :           mio_ref (&tail);
    3510              :         }
    3511              : 
    3512         6816 :       *rp = head;
    3513              :     }
    3514              : 
    3515        14209 :   mio_rparen ();
    3516        14209 : }
    3517              : 
    3518              : 
    3519              : /* Read and write an integer value.  */
    3520              : 
    3521              : static void
    3522       340169 : mio_gmp_integer (mpz_t *integer)
    3523              : {
    3524       340169 :   char *p;
    3525              : 
    3526       340169 :   if (iomode == IO_INPUT)
    3527              :     {
    3528       270348 :       if (parse_atom () != ATOM_STRING)
    3529            0 :         bad_module ("Expected integer string");
    3530              : 
    3531       270348 :       mpz_init (*integer);
    3532       270348 :       if (mpz_set_str (*integer, atom_string, 10))
    3533            0 :         bad_module ("Error converting integer");
    3534              : 
    3535       270348 :       free (atom_string);
    3536              :     }
    3537              :   else
    3538              :     {
    3539        69821 :       p = mpz_get_str (NULL, 10, *integer);
    3540        69821 :       write_atom (ATOM_STRING, p);
    3541        69821 :       free (p);
    3542              :     }
    3543       340169 : }
    3544              : 
    3545              : 
    3546              : static void
    3547         1939 : mio_gmp_real (mpfr_t *real)
    3548              : {
    3549         1939 :   mpfr_exp_t exponent;
    3550         1939 :   char *p;
    3551              : 
    3552         1939 :   if (iomode == IO_INPUT)
    3553              :     {
    3554          914 :       if (parse_atom () != ATOM_STRING)
    3555            0 :         bad_module ("Expected real string");
    3556              : 
    3557          914 :       mpfr_init (*real);
    3558          914 :       mpfr_set_str (*real, atom_string, 16, GFC_RND_MODE);
    3559          914 :       free (atom_string);
    3560              :     }
    3561              :   else
    3562              :     {
    3563         1025 :       p = mpfr_get_str (NULL, &exponent, 16, 0, *real, GFC_RND_MODE);
    3564              : 
    3565         1025 :       if (mpfr_nan_p (*real) || mpfr_inf_p (*real))
    3566              :         {
    3567           18 :           write_atom (ATOM_STRING, p);
    3568           18 :           free (p);
    3569           18 :           return;
    3570              :         }
    3571              : 
    3572         1007 :       atom_string = XCNEWVEC (char, strlen (p) + 20);
    3573              : 
    3574         1007 :       sprintf (atom_string, "0.%s@%ld", p, exponent);
    3575              : 
    3576              :       /* Fix negative numbers.  */
    3577         1007 :       if (atom_string[2] == '-')
    3578              :         {
    3579           45 :           atom_string[0] = '-';
    3580           45 :           atom_string[1] = '0';
    3581           45 :           atom_string[2] = '.';
    3582              :         }
    3583              : 
    3584         1007 :       write_atom (ATOM_STRING, atom_string);
    3585              : 
    3586         1007 :       free (atom_string);
    3587         1007 :       free (p);
    3588              :     }
    3589              : }
    3590              : 
    3591              : 
    3592              : /* Save and restore the shape of an array constructor.  */
    3593              : 
    3594              : static void
    3595        21001 : mio_shape (mpz_t **pshape, int rank)
    3596              : {
    3597        21001 :   mpz_t *shape;
    3598        21001 :   atom_type t;
    3599        21001 :   int n;
    3600              : 
    3601              :   /* A NULL shape is represented by ().  */
    3602        21001 :   mio_lparen ();
    3603              : 
    3604        21001 :   if (iomode == IO_OUTPUT)
    3605              :     {
    3606         4006 :       shape = *pshape;
    3607         4006 :       if (!shape)
    3608              :         {
    3609         3420 :           mio_rparen ();
    3610         3420 :           return;
    3611              :         }
    3612              :     }
    3613              :   else
    3614              :     {
    3615        16995 :       t = peek_atom ();
    3616        16995 :       if (t == ATOM_RPAREN)
    3617              :         {
    3618        15634 :           *pshape = NULL;
    3619        15634 :           mio_rparen ();
    3620        15634 :           return;
    3621              :         }
    3622              : 
    3623         1361 :       shape = gfc_get_shape (rank);
    3624         1361 :       *pshape = shape;
    3625              :     }
    3626              : 
    3627         4033 :   for (n = 0; n < rank; n++)
    3628         2086 :     mio_gmp_integer (&shape[n]);
    3629              : 
    3630         1947 :   mio_rparen ();
    3631              : }
    3632              : 
    3633              : 
    3634              : static const mstring expr_types[] = {
    3635              :     minit ("OP", EXPR_OP),
    3636              :     minit ("FUNCTION", EXPR_FUNCTION),
    3637              :     minit ("CONSTANT", EXPR_CONSTANT),
    3638              :     minit ("VARIABLE", EXPR_VARIABLE),
    3639              :     minit ("SUBSTRING", EXPR_SUBSTRING),
    3640              :     minit ("STRUCTURE", EXPR_STRUCTURE),
    3641              :     minit ("ARRAY", EXPR_ARRAY),
    3642              :     minit ("NULL", EXPR_NULL),
    3643              :     minit ("COMPCALL", EXPR_COMPCALL),
    3644              :     minit ("PPC", EXPR_PPC),
    3645              :     minit ("CONDITIONAL", EXPR_CONDITIONAL),
    3646              :     minit (NULL, -1),
    3647              : };
    3648              : 
    3649              : /* INTRINSIC_ASSIGN is missing because it is used as an index for
    3650              :    generic operators, not in expressions.  INTRINSIC_USER is also
    3651              :    replaced by the correct function name by the time we see it.  */
    3652              : 
    3653              : static const mstring intrinsics[] =
    3654              : {
    3655              :     minit ("UPLUS", INTRINSIC_UPLUS),
    3656              :     minit ("UMINUS", INTRINSIC_UMINUS),
    3657              :     minit ("PLUS", INTRINSIC_PLUS),
    3658              :     minit ("MINUS", INTRINSIC_MINUS),
    3659              :     minit ("TIMES", INTRINSIC_TIMES),
    3660              :     minit ("DIVIDE", INTRINSIC_DIVIDE),
    3661              :     minit ("POWER", INTRINSIC_POWER),
    3662              :     minit ("CONCAT", INTRINSIC_CONCAT),
    3663              :     minit ("AND", INTRINSIC_AND),
    3664              :     minit ("OR", INTRINSIC_OR),
    3665              :     minit ("EQV", INTRINSIC_EQV),
    3666              :     minit ("NEQV", INTRINSIC_NEQV),
    3667              :     minit ("EQ_SIGN", INTRINSIC_EQ),
    3668              :     minit ("EQ", INTRINSIC_EQ_OS),
    3669              :     minit ("NE_SIGN", INTRINSIC_NE),
    3670              :     minit ("NE", INTRINSIC_NE_OS),
    3671              :     minit ("GT_SIGN", INTRINSIC_GT),
    3672              :     minit ("GT", INTRINSIC_GT_OS),
    3673              :     minit ("GE_SIGN", INTRINSIC_GE),
    3674              :     minit ("GE", INTRINSIC_GE_OS),
    3675              :     minit ("LT_SIGN", INTRINSIC_LT),
    3676              :     minit ("LT", INTRINSIC_LT_OS),
    3677              :     minit ("LE_SIGN", INTRINSIC_LE),
    3678              :     minit ("LE", INTRINSIC_LE_OS),
    3679              :     minit ("NOT", INTRINSIC_NOT),
    3680              :     minit ("PARENTHESES", INTRINSIC_PARENTHESES),
    3681              :     minit ("USER", INTRINSIC_USER),
    3682              :     minit (NULL, -1)
    3683              : };
    3684              : 
    3685              : 
    3686              : /* Remedy a couple of situations where the gfc_expr's can be defective.  */
    3687              : 
    3688              : static void
    3689       411066 : fix_mio_expr (gfc_expr *e)
    3690              : {
    3691       411066 :   gfc_symtree *ns_st = NULL;
    3692       411066 :   const char *fname;
    3693              : 
    3694       411066 :   if (iomode != IO_OUTPUT)
    3695              :     return;
    3696              : 
    3697        98633 :   if (e->symtree)
    3698              :     {
    3699              :       /* If this is a symtree for a symbol that came from a contained module
    3700              :          namespace, it has a unique name and we should look in the current
    3701              :          namespace to see if the required, non-contained symbol is available
    3702              :          yet. If so, the latter should be written.  */
    3703         9946 :       if (e->symtree->n.sym && check_unique_name (e->symtree->name))
    3704              :         {
    3705          613 :           const char *name = e->symtree->n.sym->name;
    3706          613 :           if (gfc_fl_struct (e->symtree->n.sym->attr.flavor))
    3707            0 :             name = gfc_dt_upper_string (name);
    3708          613 :           ns_st = gfc_find_symtree (gfc_current_ns->sym_root, name);
    3709              :         }
    3710              : 
    3711              :       /* On the other hand, if the existing symbol is the module name or the
    3712              :          new symbol is a dummy argument, do not do the promotion.  */
    3713          613 :       if (ns_st && ns_st->n.sym
    3714           23 :           && ns_st->n.sym->attr.flavor != FL_MODULE
    3715           22 :           && !e->symtree->n.sym->attr.dummy)
    3716           21 :         e->symtree = ns_st;
    3717              :     }
    3718        88687 :   else if (e->expr_type == EXPR_FUNCTION
    3719            2 :            && (e->value.function.name || e->value.function.isym))
    3720              :     {
    3721            2 :       gfc_symbol *sym;
    3722              : 
    3723              :       /* In some circumstances, a function used in an initialization
    3724              :          expression, in one use associated module, can fail to be
    3725              :          coupled to its symtree when used in a specification
    3726              :          expression in another module.  */
    3727            2 :       fname = e->value.function.esym ? e->value.function.esym->name
    3728            2 :                                      : e->value.function.isym->name;
    3729            2 :       e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);
    3730              : 
    3731            2 :       if (e->symtree)
    3732            1 :         return;
    3733              : 
    3734              :       /* This is probably a reference to a private procedure from another
    3735              :          module.  To prevent a segfault, make a generic with no specific
    3736              :          instances.  If this module is used, without the required
    3737              :          specific coming from somewhere, the appropriate error message
    3738              :          is issued.  */
    3739            1 :       gfc_get_symbol (fname, gfc_current_ns, &sym);
    3740            1 :       sym->attr.flavor = FL_PROCEDURE;
    3741            1 :       sym->attr.generic = 1;
    3742            1 :       e->symtree = gfc_find_symtree (gfc_current_ns->sym_root, fname);
    3743            1 :       gfc_commit_symbol (sym);
    3744              :     }
    3745              : }
    3746              : 
    3747              : 
    3748              : /* Read and write expressions.  The form "()" is allowed to indicate a
    3749              :    NULL expression.  */
    3750              : 
    3751              : static void
    3752       812312 : mio_expr (gfc_expr **ep)
    3753              : {
    3754       812312 :   HOST_WIDE_INT hwi;
    3755       812312 :   gfc_expr *e;
    3756       812312 :   atom_type t;
    3757       812312 :   int flag;
    3758              : 
    3759       812312 :   mio_lparen ();
    3760              : 
    3761       812312 :   if (iomode == IO_OUTPUT)
    3762              :     {
    3763       246353 :       if (*ep == NULL)
    3764              :         {
    3765       147720 :           mio_rparen ();
    3766       548966 :           return;
    3767              :         }
    3768              : 
    3769        98633 :       e = *ep;
    3770        98633 :       MIO_NAME (expr_t) (e->expr_type, expr_types);
    3771              :     }
    3772              :   else
    3773              :     {
    3774       565959 :       t = parse_atom ();
    3775       565959 :       if (t == ATOM_RPAREN)
    3776              :         {
    3777       253526 :           *ep = NULL;
    3778       253526 :           return;
    3779              :         }
    3780              : 
    3781       312433 :       if (t != ATOM_NAME)
    3782            0 :         bad_module ("Expected expression type");
    3783              : 
    3784       312433 :       e = *ep = gfc_get_expr ();
    3785       312433 :       e->where = gfc_current_locus;
    3786       312433 :       e->expr_type = (expr_t) find_enum (expr_types);
    3787              :     }
    3788              : 
    3789       411066 :   mio_typespec (&e->ts);
    3790       411066 :   mio_integer (&e->rank);
    3791              : 
    3792       411066 :   fix_mio_expr (e);
    3793              : 
    3794       411066 :   switch (e->expr_type)
    3795              :     {
    3796         1589 :     case EXPR_OP:
    3797         1589 :       e->value.op.op
    3798         1589 :         = MIO_NAME (gfc_intrinsic_op) (e->value.op.op, intrinsics);
    3799              : 
    3800         1589 :       switch (e->value.op.op)
    3801              :         {
    3802          447 :         case INTRINSIC_UPLUS:
    3803          447 :         case INTRINSIC_UMINUS:
    3804          447 :         case INTRINSIC_NOT:
    3805          447 :         case INTRINSIC_PARENTHESES:
    3806          447 :           mio_expr (&e->value.op.op1);
    3807          447 :           break;
    3808              : 
    3809         1072 :         case INTRINSIC_PLUS:
    3810         1072 :         case INTRINSIC_MINUS:
    3811         1072 :         case INTRINSIC_TIMES:
    3812         1072 :         case INTRINSIC_DIVIDE:
    3813         1072 :         case INTRINSIC_POWER:
    3814         1072 :         case INTRINSIC_CONCAT:
    3815         1072 :         case INTRINSIC_AND:
    3816         1072 :         case INTRINSIC_OR:
    3817         1072 :         case INTRINSIC_EQV:
    3818         1072 :         case INTRINSIC_NEQV:
    3819         1072 :         case INTRINSIC_EQ:
    3820         1072 :         case INTRINSIC_EQ_OS:
    3821         1072 :         case INTRINSIC_NE:
    3822         1072 :         case INTRINSIC_NE_OS:
    3823         1072 :         case INTRINSIC_GT:
    3824         1072 :         case INTRINSIC_GT_OS:
    3825         1072 :         case INTRINSIC_GE:
    3826         1072 :         case INTRINSIC_GE_OS:
    3827         1072 :         case INTRINSIC_LT:
    3828         1072 :         case INTRINSIC_LT_OS:
    3829         1072 :         case INTRINSIC_LE:
    3830         1072 :         case INTRINSIC_LE_OS:
    3831         1072 :           mio_expr (&e->value.op.op1);
    3832         1072 :           mio_expr (&e->value.op.op2);
    3833         1072 :           break;
    3834              : 
    3835           70 :         case INTRINSIC_USER:
    3836              :           /* INTRINSIC_USER should not appear in resolved expressions,
    3837              :              though for UDRs we need to stream unresolved ones.  */
    3838           70 :           if (iomode == IO_OUTPUT)
    3839           34 :             write_atom (ATOM_STRING, e->value.op.uop->name);
    3840              :           else
    3841              :             {
    3842           36 :               char *name = read_string ();
    3843           36 :               const char *uop_name = find_use_name (name, true);
    3844           36 :               if (uop_name == NULL)
    3845              :                 {
    3846            0 :                   size_t len = strlen (name);
    3847            0 :                   char *name2 = XCNEWVEC (char, len + 2);
    3848            0 :                   memcpy (name2, name, len);
    3849            0 :                   name2[len] = ' ';
    3850            0 :                   name2[len + 1] = '\0';
    3851            0 :                   free (name);
    3852            0 :                   uop_name = name = name2;
    3853              :                 }
    3854           36 :               e->value.op.uop = gfc_get_uop (uop_name);
    3855           36 :               free (name);
    3856              :             }
    3857           70 :           mio_expr (&e->value.op.op1);
    3858           70 :           mio_expr (&e->value.op.op2);
    3859           70 :           break;
    3860              : 
    3861            0 :         default:
    3862            0 :           bad_module ("Bad operator");
    3863              :         }
    3864              : 
    3865              :       break;
    3866              : 
    3867            2 :     case EXPR_CONDITIONAL:
    3868            2 :       mio_expr (&e->value.conditional.condition);
    3869            2 :       mio_expr (&e->value.conditional.true_expr);
    3870            2 :       mio_expr (&e->value.conditional.false_expr);
    3871            2 :       break;
    3872              : 
    3873         2523 :     case EXPR_FUNCTION:
    3874         2523 :       mio_symtree_ref (&e->symtree);
    3875         2523 :       mio_actual_arglist (&e->value.function.actual, false);
    3876              : 
    3877         2523 :       if (iomode == IO_OUTPUT)
    3878              :         {
    3879         1296 :           e->value.function.name
    3880         1296 :             = mio_allocated_string (e->value.function.name);
    3881         1296 :           if (e->value.function.esym)
    3882          131 :             flag = 1;
    3883         1165 :           else if (e->ref)
    3884          104 :             flag = 2;
    3885         1061 :           else if (e->value.function.isym == NULL)
    3886          176 :             flag = 3;
    3887              :           else
    3888          885 :             flag = 0;
    3889         1296 :           mio_integer (&flag);
    3890         1296 :           switch (flag)
    3891              :             {
    3892          131 :             case 1:
    3893          131 :               mio_symbol_ref (&e->value.function.esym);
    3894          131 :               break;
    3895          104 :             case 2:
    3896          104 :               mio_ref_list (&e->ref);
    3897          104 :               break;
    3898              :             case 3:
    3899              :               break;
    3900          885 :             default:
    3901          885 :               write_atom (ATOM_STRING, e->value.function.isym->name);
    3902              :             }
    3903              :         }
    3904              :       else
    3905              :         {
    3906         1227 :           require_atom (ATOM_STRING);
    3907         1227 :           if (atom_string[0] == '\0')
    3908          662 :             e->value.function.name = NULL;
    3909              :           else
    3910          565 :             e->value.function.name = gfc_get_string ("%s", atom_string);
    3911         1227 :           free (atom_string);
    3912              : 
    3913         1227 :           mio_integer (&flag);
    3914         1227 :           switch (flag)
    3915              :             {
    3916          138 :             case 1:
    3917          138 :               mio_symbol_ref (&e->value.function.esym);
    3918          138 :               break;
    3919           72 :             case 2:
    3920           72 :               mio_ref_list (&e->ref);
    3921           72 :               break;
    3922              :             case 3:
    3923              :               break;
    3924          867 :             default:
    3925          867 :               require_atom (ATOM_STRING);
    3926          867 :               e->value.function.isym = gfc_find_function (atom_string);
    3927          867 :               free (atom_string);
    3928              :             }
    3929              :         }
    3930              : 
    3931              :       break;
    3932              : 
    3933        14033 :     case EXPR_VARIABLE:
    3934        14033 :       mio_symtree_ref (&e->symtree);
    3935        14033 :       mio_ref_list (&e->ref);
    3936        14033 :       break;
    3937              : 
    3938            0 :     case EXPR_SUBSTRING:
    3939            0 :       e->value.character.string = const_cast<gfc_char_t *>
    3940            0 :         (mio_allocated_wide_string (e->value.character.string,
    3941            0 :                                     e->value.character.length));
    3942            0 :       mio_ref_list (&e->ref);
    3943            0 :       break;
    3944              : 
    3945        21001 :     case EXPR_STRUCTURE:
    3946        21001 :     case EXPR_ARRAY:
    3947        21001 :       mio_constructor (&e->value.constructor);
    3948        21001 :       mio_shape (&e->shape, e->rank);
    3949        21001 :       break;
    3950              : 
    3951       348517 :     case EXPR_CONSTANT:
    3952       348517 :       switch (e->ts.type)
    3953              :         {
    3954       338083 :         case BT_INTEGER:
    3955       338083 :         case BT_UNSIGNED:
    3956       338083 :           mio_gmp_integer (&e->value.integer);
    3957       338083 :           break;
    3958              : 
    3959         1803 :         case BT_REAL:
    3960         1803 :           gfc_set_model_kind (e->ts.kind);
    3961         1803 :           mio_gmp_real (&e->value.real);
    3962         1803 :           break;
    3963              : 
    3964           68 :         case BT_COMPLEX:
    3965           68 :           gfc_set_model_kind (e->ts.kind);
    3966           68 :           mio_gmp_real (&mpc_realref (e->value.complex));
    3967           68 :           mio_gmp_real (&mpc_imagref (e->value.complex));
    3968           68 :           break;
    3969              : 
    3970          157 :         case BT_LOGICAL:
    3971          157 :           mio_integer (&e->value.logical);
    3972          157 :           break;
    3973              : 
    3974         8406 :         case BT_CHARACTER:
    3975         8406 :           hwi = e->value.character.length;
    3976         8406 :           mio_hwi (&hwi);
    3977         8406 :           e->value.character.length = hwi;
    3978        16812 :           e->value.character.string = const_cast<gfc_char_t *>
    3979         8406 :             (mio_allocated_wide_string (e->value.character.string,
    3980              :                                         e->value.character.length));
    3981         8406 :           break;
    3982              : 
    3983            0 :         default:
    3984            0 :           bad_module ("Bad type in constant expression");
    3985              :         }
    3986              : 
    3987              :       break;
    3988              : 
    3989              :     case EXPR_NULL:
    3990              :       break;
    3991              : 
    3992            0 :     case EXPR_COMPCALL:
    3993            0 :     case EXPR_PPC:
    3994            0 :     case EXPR_UNKNOWN:
    3995            0 :       gcc_unreachable ();
    3996       411066 :       break;
    3997              :     }
    3998              : 
    3999              :   /* PDT types store the expression specification list here. */
    4000       411066 :   mio_actual_arglist (&e->param_list, true);
    4001              : 
    4002       411066 :   mio_rparen ();
    4003              : }
    4004              : 
    4005              : 
    4006              : /* Read and write namelists.  */
    4007              : 
    4008              : static void
    4009      1227033 : mio_namelist (gfc_symbol *sym)
    4010              : {
    4011      1227033 :   gfc_namelist *n, *m;
    4012              : 
    4013      1227033 :   mio_lparen ();
    4014              : 
    4015      1227033 :   if (iomode == IO_OUTPUT)
    4016              :     {
    4017       233652 :       for (n = sym->namelist; n; n = n->next)
    4018           84 :         mio_symbol_ref (&n->sym);
    4019              :     }
    4020              :   else
    4021              :     {
    4022              :       m = NULL;
    4023       993554 :       while (peek_atom () != ATOM_RPAREN)
    4024              :         {
    4025           89 :           n = gfc_get_namelist ();
    4026           89 :           mio_symbol_ref (&n->sym);
    4027              : 
    4028           89 :           if (sym->namelist == NULL)
    4029           53 :             sym->namelist = n;
    4030              :           else
    4031           36 :             m->next = n;
    4032              : 
    4033              :           m = n;
    4034              :         }
    4035       993465 :       sym->namelist_tail = m;
    4036              :     }
    4037              : 
    4038      1227033 :   mio_rparen ();
    4039      1227033 : }
    4040              : 
    4041              : 
    4042              : /* Save/restore lists of gfc_interface structures.  When loading an
    4043              :    interface, we are really appending to the existing list of
    4044              :    interfaces.  Checking for duplicate and ambiguous interfaces has to
    4045              :    be done later when all symbols have been loaded.  */
    4046              : 
    4047              : pointer_info *
    4048       633897 : mio_interface_rest (gfc_interface **ip)
    4049              : {
    4050       633897 :   gfc_interface *tail, *p;
    4051       633897 :   pointer_info *pi = NULL;
    4052              : 
    4053       633897 :   if (iomode == IO_OUTPUT)
    4054              :     {
    4055       269311 :       if (ip != NULL)
    4056       261046 :         for (p = *ip; p; p = p->next)
    4057        16348 :           mio_symbol_ref (&p->sym);
    4058              :     }
    4059              :   else
    4060              :     {
    4061       364586 :       if (*ip == NULL)
    4062              :         tail = NULL;
    4063              :       else
    4064              :         {
    4065              :           tail = *ip;
    4066         5136 :           while (tail->next)
    4067              :             tail = tail->next;
    4068              :         }
    4069              : 
    4070       527603 :       for (;;)
    4071              :         {
    4072       527603 :           if (peek_atom () == ATOM_RPAREN)
    4073              :             break;
    4074              : 
    4075       163017 :           p = gfc_get_interface ();
    4076       163017 :           p->where = gfc_current_locus;
    4077       163017 :           pi = mio_symbol_ref (&p->sym);
    4078              : 
    4079       163017 :           if (tail == NULL)
    4080        53029 :             *ip = p;
    4081              :           else
    4082       109988 :             tail->next = p;
    4083              : 
    4084              :           tail = p;
    4085              :         }
    4086              :     }
    4087              : 
    4088       633897 :   mio_rparen ();
    4089       633897 :   return pi;
    4090              : }
    4091              : 
    4092              : 
    4093              : /* Save/restore a nameless operator interface.  */
    4094              : 
    4095              : static void
    4096       569445 : mio_interface (gfc_interface **ip)
    4097              : {
    4098       258660 :   mio_lparen ();
    4099       310785 :   mio_interface_rest (ip);
    4100       258660 : }
    4101              : 
    4102              : 
    4103              : /* Save/restore a named operator interface.  */
    4104              : 
    4105              : static void
    4106        10651 : mio_symbol_interface (const char **name, const char **module,
    4107              :                       gfc_interface **ip)
    4108              : {
    4109        10651 :   mio_lparen ();
    4110        10651 :   mio_pool_string (name);
    4111        10651 :   mio_pool_string (module);
    4112        10651 :   mio_interface_rest (ip);
    4113        10651 : }
    4114              : 
    4115              : 
    4116              : static void
    4117      1227033 : mio_namespace_ref (gfc_namespace **nsp)
    4118              : {
    4119      1227033 :   gfc_namespace *ns;
    4120      1227033 :   pointer_info *p;
    4121              : 
    4122      1227033 :   p = mio_pointer_ref (nsp);
    4123              : 
    4124      1227033 :   if (p->type == P_UNKNOWN)
    4125       249998 :     p->type = P_NAMESPACE;
    4126              : 
    4127      1227033 :   if (iomode == IO_INPUT && p->integer != 0)
    4128              :     {
    4129       221950 :       ns = (gfc_namespace *) p->u.pointer;
    4130       221950 :       if (ns == NULL)
    4131              :         {
    4132       221681 :           ns = gfc_get_namespace (NULL, 0);
    4133       221681 :           associate_integer_pointer (p, ns);
    4134              :         }
    4135              :       else
    4136          269 :         ns->refs++;
    4137              :     }
    4138      1227033 : }
    4139              : 
    4140              : 
    4141              : /* Save/restore the f2k_derived namespace of a derived-type symbol.  */
    4142              : 
    4143              : static gfc_namespace* current_f2k_derived;
    4144              : 
    4145              : static void
    4146        96556 : mio_typebound_proc (gfc_typebound_proc** proc)
    4147              : {
    4148        96556 :   int flag;
    4149        96556 :   int overriding_flag;
    4150              : 
    4151        96556 :   if (iomode == IO_INPUT)
    4152              :     {
    4153        54371 :       *proc = gfc_get_typebound_proc (NULL);
    4154        54371 :       (*proc)->where = gfc_current_locus;
    4155              :     }
    4156        96556 :   gcc_assert (*proc);
    4157              : 
    4158        96556 :   mio_lparen ();
    4159              : 
    4160        96556 :   (*proc)->access = MIO_NAME (gfc_access) ((*proc)->access, access_types);
    4161              : 
    4162              :   /* IO the NON_OVERRIDABLE/DEFERRED combination.  */
    4163        96556 :   gcc_assert (!((*proc)->deferred && (*proc)->non_overridable));
    4164        96556 :   overriding_flag = ((*proc)->deferred << 1) | (*proc)->non_overridable;
    4165        96556 :   overriding_flag = mio_name (overriding_flag, binding_overriding);
    4166        96556 :   (*proc)->deferred = ((overriding_flag & 2) != 0);
    4167        96556 :   (*proc)->non_overridable = ((overriding_flag & 1) != 0);
    4168        96556 :   gcc_assert (!((*proc)->deferred && (*proc)->non_overridable));
    4169              : 
    4170        96556 :   (*proc)->nopass = mio_name ((*proc)->nopass, binding_passing);
    4171        96556 :   (*proc)->is_generic = mio_name ((*proc)->is_generic, binding_generic);
    4172        96556 :   (*proc)->ppc = mio_name((*proc)->ppc, binding_ppc);
    4173              : 
    4174        96556 :   mio_pool_string (&((*proc)->pass_arg));
    4175              : 
    4176        96556 :   flag = (int) (*proc)->pass_arg_num;
    4177        96556 :   mio_integer (&flag);
    4178        96556 :   (*proc)->pass_arg_num = (unsigned) flag;
    4179              : 
    4180        96556 :   if ((*proc)->is_generic)
    4181              :     {
    4182         2789 :       gfc_tbp_generic* g;
    4183         2789 :       int iop;
    4184              : 
    4185         2789 :       mio_lparen ();
    4186              : 
    4187         2789 :       if (iomode == IO_OUTPUT)
    4188         3340 :         for (g = (*proc)->u.generic; g; g = g->next)
    4189              :           {
    4190         1869 :             iop = (int) g->is_operator;
    4191         1869 :             mio_integer (&iop);
    4192         1869 :             mio_allocated_string (g->specific_st->name);
    4193              :           }
    4194              :       else
    4195              :         {
    4196         1318 :           (*proc)->u.generic = NULL;
    4197         2937 :           while (peek_atom () != ATOM_RPAREN)
    4198              :             {
    4199         1619 :               gfc_symtree** sym_root;
    4200              : 
    4201         1619 :               g = gfc_get_tbp_generic ();
    4202         1619 :               g->specific = NULL;
    4203              : 
    4204         1619 :               mio_integer (&iop);
    4205         1619 :               g->is_operator = (bool) iop;
    4206              : 
    4207         1619 :               require_atom (ATOM_STRING);
    4208         1619 :               sym_root = &current_f2k_derived->tb_sym_root;
    4209         1619 :               g->specific_st = gfc_get_tbp_symtree (sym_root, atom_string);
    4210         1619 :               free (atom_string);
    4211              : 
    4212         1619 :               g->next = (*proc)->u.generic;
    4213         1619 :               (*proc)->u.generic = g;
    4214              :             }
    4215              :         }
    4216              : 
    4217         2789 :       mio_rparen ();
    4218              :     }
    4219        93767 :   else if (!(*proc)->ppc)
    4220         9311 :     mio_symtree_ref (&(*proc)->u.specific);
    4221              : 
    4222        96556 :   mio_rparen ();
    4223        96556 : }
    4224              : 
    4225              : /* Walker-callback function for this purpose.  */
    4226              : static void
    4227        10780 : mio_typebound_symtree (gfc_symtree* st)
    4228              : {
    4229        10780 :   if (iomode == IO_OUTPUT && !st->n.tb)
    4230              :     return;
    4231              : 
    4232        10780 :   if (iomode == IO_OUTPUT)
    4233              :     {
    4234         5725 :       mio_lparen ();
    4235         5725 :       mio_allocated_string (st->name);
    4236              :     }
    4237              :   /* For IO_INPUT, the above is done in mio_f2k_derived.  */
    4238              : 
    4239        10780 :   mio_typebound_proc (&st->n.tb);
    4240        10780 :   mio_rparen ();
    4241              : }
    4242              : 
    4243              : /* IO a full symtree (in all depth).  */
    4244              : static void
    4245        62076 : mio_full_typebound_tree (gfc_symtree** root)
    4246              : {
    4247        62076 :   mio_lparen ();
    4248              : 
    4249        62076 :   if (iomode == IO_OUTPUT)
    4250        26430 :     gfc_traverse_symtree (*root, &mio_typebound_symtree);
    4251              :   else
    4252              :     {
    4253        40701 :       while (peek_atom () == ATOM_LPAREN)
    4254              :         {
    4255         5055 :           gfc_symtree* st;
    4256              : 
    4257         5055 :           mio_lparen ();
    4258              : 
    4259         5055 :           require_atom (ATOM_STRING);
    4260         5055 :           st = gfc_get_tbp_symtree (root, atom_string);
    4261         5055 :           free (atom_string);
    4262              : 
    4263         5055 :           mio_typebound_symtree (st);
    4264              :         }
    4265              :     }
    4266              : 
    4267        62076 :   mio_rparen ();
    4268        62076 : }
    4269              : 
    4270              : static void
    4271         1203 : mio_finalizer (gfc_finalizer **f)
    4272              : {
    4273         1203 :   if (iomode == IO_OUTPUT)
    4274              :     {
    4275          576 :       gcc_assert (*f);
    4276          576 :       gcc_assert ((*f)->proc_tree); /* Should already be resolved.  */
    4277          576 :       mio_symtree_ref (&(*f)->proc_tree);
    4278              :     }
    4279              :   else
    4280              :     {
    4281          627 :       *f = gfc_get_finalizer ();
    4282          627 :       (*f)->where = gfc_current_locus; /* Value should not matter.  */
    4283          627 :       (*f)->next = NULL;
    4284              : 
    4285          627 :       mio_symtree_ref (&(*f)->proc_tree);
    4286          627 :       (*f)->proc_sym = NULL;
    4287              :     }
    4288         1203 : }
    4289              : 
    4290              : static void
    4291        31038 : mio_f2k_derived (gfc_namespace *f2k)
    4292              : {
    4293        31038 :   current_f2k_derived = f2k;
    4294              : 
    4295              :   /* Handle the list of finalizer procedures.  */
    4296        31038 :   mio_lparen ();
    4297        31038 :   if (iomode == IO_OUTPUT)
    4298              :     {
    4299        13215 :       gfc_finalizer *f;
    4300        13791 :       for (f = f2k->finalizers; f; f = f->next)
    4301          576 :         mio_finalizer (&f);
    4302              :     }
    4303              :   else
    4304              :     {
    4305        17823 :       f2k->finalizers = NULL;
    4306        18450 :       while (peek_atom () != ATOM_RPAREN)
    4307              :         {
    4308          627 :           gfc_finalizer *cur = NULL;
    4309          627 :           mio_finalizer (&cur);
    4310          627 :           cur->next = f2k->finalizers;
    4311          627 :           f2k->finalizers = cur;
    4312              :         }
    4313              :     }
    4314        31038 :   mio_rparen ();
    4315              : 
    4316              :   /* Handle type-bound procedures.  */
    4317        31038 :   mio_full_typebound_tree (&f2k->tb_sym_root);
    4318              : 
    4319              :   /* Type-bound user operators.  */
    4320        31038 :   mio_full_typebound_tree (&f2k->tb_uop_root);
    4321              : 
    4322              :   /* Type-bound intrinsic operators.  */
    4323        31038 :   mio_lparen ();
    4324        31038 :   if (iomode == IO_OUTPUT)
    4325              :     {
    4326              :       int op;
    4327       383235 :       for (op = GFC_INTRINSIC_BEGIN; op != GFC_INTRINSIC_END; ++op)
    4328              :         {
    4329       370020 :           gfc_intrinsic_op realop;
    4330              : 
    4331       370020 :           if (op == INTRINSIC_USER || !f2k->tb_op[op])
    4332       369318 :             continue;
    4333              : 
    4334          702 :           mio_lparen ();
    4335          702 :           realop = (gfc_intrinsic_op) op;
    4336          702 :           mio_intrinsic_op (&realop);
    4337          702 :           mio_typebound_proc (&f2k->tb_op[op]);
    4338          702 :           mio_rparen ();
    4339              :         }
    4340              :     }
    4341              :   else
    4342        18441 :     while (peek_atom () != ATOM_RPAREN)
    4343              :       {
    4344          618 :         gfc_intrinsic_op op = GFC_INTRINSIC_BEGIN; /* Silence GCC.  */
    4345              : 
    4346          618 :         mio_lparen ();
    4347          618 :         mio_intrinsic_op (&op);
    4348          618 :         mio_typebound_proc (&f2k->tb_op[op]);
    4349          618 :         mio_rparen ();
    4350              :       }
    4351        31038 :   mio_rparen ();
    4352        31038 : }
    4353              : 
    4354              : static void
    4355      1227033 : mio_full_f2k_derived (gfc_symbol *sym)
    4356              : {
    4357      1227033 :   mio_lparen ();
    4358              : 
    4359      1227033 :   if (iomode == IO_OUTPUT)
    4360              :     {
    4361       233568 :       if (sym->f2k_derived)
    4362        13215 :         mio_f2k_derived (sym->f2k_derived);
    4363              :     }
    4364              :   else
    4365              :     {
    4366       993465 :       if (peek_atom () != ATOM_RPAREN)
    4367              :         {
    4368        17823 :           gfc_namespace *ns;
    4369              : 
    4370        17823 :           sym->f2k_derived = gfc_get_namespace (NULL, 0);
    4371              : 
    4372              :           /* PDT templates make use of the mechanisms for formal args
    4373              :              and so the parameter symbols are stored in the formal
    4374              :              namespace.  Transfer the sym_root to f2k_derived and then
    4375              :              free the formal namespace since it is uneeded.  */
    4376        17823 :           if (sym->attr.pdt_template && sym->formal && sym->formal->sym)
    4377              :             {
    4378            6 :               ns = sym->formal->sym->ns;
    4379            6 :               sym->f2k_derived->sym_root = ns->sym_root;
    4380            6 :               ns->sym_root = NULL;
    4381            6 :               ns->refs++;
    4382            6 :               gfc_free_namespace (ns);
    4383            6 :               ns = NULL;
    4384              :             }
    4385              : 
    4386        17823 :           mio_f2k_derived (sym->f2k_derived);
    4387              :         }
    4388              :       else
    4389       975642 :         gcc_assert (!sym->f2k_derived);
    4390              :     }
    4391              : 
    4392      1227033 :   mio_rparen ();
    4393      1227033 : }
    4394              : 
    4395              : static const mstring omp_declare_simd_clauses[] =
    4396              : {
    4397              :     minit ("INBRANCH", 0),
    4398              :     minit ("NOTINBRANCH", 1),
    4399              :     minit ("SIMDLEN", 2),
    4400              :     minit ("UNIFORM", 3),
    4401              :     minit ("LINEAR", 4),
    4402              :     minit ("ALIGNED", 5),
    4403              :     minit ("LINEAR_REF", 33),
    4404              :     minit ("LINEAR_VAL", 34),
    4405              :     minit ("LINEAR_UVAL", 35),
    4406              :     minit (NULL, -1)
    4407              : };
    4408              : 
    4409              : /* Handle OpenMP's declare-simd clauses.  */
    4410              : 
    4411              : static void
    4412          148 : mio_omp_declare_simd_clauses (gfc_omp_clauses **clausesp)
    4413              : {
    4414          148 :   if (iomode == IO_OUTPUT)
    4415              :     {
    4416           94 :       gfc_omp_clauses *clauses = *clausesp;
    4417           94 :       gfc_omp_namelist *n;
    4418              : 
    4419           94 :       write_atom (ATOM_NAME, "OMP_DECLARE_SIMD");
    4420           94 :       if (clauses->inbranch)
    4421           10 :         mio_name (0, omp_declare_simd_clauses);
    4422           94 :       if (clauses->notinbranch)
    4423           23 :         mio_name (1, omp_declare_simd_clauses);
    4424           94 :       if (clauses->simdlen_expr)
    4425              :         {
    4426           37 :           mio_name (2, omp_declare_simd_clauses);
    4427           37 :           mio_expr (&clauses->simdlen_expr);
    4428              :         }
    4429          151 :       for (n = clauses->lists[OMP_LIST_UNIFORM]; n; n = n->next)
    4430              :         {
    4431           57 :           mio_name (3, omp_declare_simd_clauses);
    4432           57 :           mio_symbol_ref (&n->sym);
    4433              :         }
    4434          146 :       for (n = clauses->lists[OMP_LIST_LINEAR]; n; n = n->next)
    4435              :         {
    4436           52 :           if (n->u.linear.op == OMP_LINEAR_DEFAULT)
    4437           33 :             mio_name (4, omp_declare_simd_clauses);
    4438              :           else
    4439           19 :             mio_name (32 + n->u.linear.op, omp_declare_simd_clauses);
    4440           52 :           mio_symbol_ref (&n->sym);
    4441           52 :           mio_expr (&n->expr);
    4442              :         }
    4443          100 :       for (n = clauses->lists[OMP_LIST_ALIGNED]; n; n = n->next)
    4444              :         {
    4445            6 :           mio_name (5, omp_declare_simd_clauses);
    4446            6 :           mio_symbol_ref (&n->sym);
    4447            6 :           mio_expr (&n->expr);
    4448              :         }
    4449              :     }
    4450              :   else
    4451              :     {
    4452           54 :       if (peek_atom () != ATOM_NAME)
    4453           18 :         return;
    4454              : 
    4455           36 :       gfc_omp_namelist **ptrs[3] = { NULL, NULL, NULL };
    4456           36 :       gfc_omp_clauses *clauses = *clausesp = gfc_get_omp_clauses ();
    4457           36 :       ptrs[0] = &clauses->lists[OMP_LIST_UNIFORM];
    4458           36 :       ptrs[1] = &clauses->lists[OMP_LIST_LINEAR];
    4459           36 :       ptrs[2] = &clauses->lists[OMP_LIST_ALIGNED];
    4460              : 
    4461          181 :       while (peek_atom () == ATOM_NAME)
    4462              :         {
    4463          109 :           gfc_omp_namelist *n;
    4464          109 :           int t = mio_name (0, omp_declare_simd_clauses);
    4465              : 
    4466          109 :           switch (t)
    4467              :             {
    4468            0 :             case 0: clauses->inbranch = true; break;
    4469           10 :             case 1: clauses->notinbranch = true; break;
    4470           19 :             case 2: mio_expr (&clauses->simdlen_expr); break;
    4471           77 :             case 3:
    4472           77 :             case 4:
    4473           77 :             case 5:
    4474           77 :               *ptrs[t - 3] = n = gfc_get_omp_namelist ();
    4475           80 :             finish_namelist:
    4476           80 :               n->where = gfc_current_locus;
    4477           80 :               ptrs[t - 3] = &n->next;
    4478           80 :               mio_symbol_ref (&n->sym);
    4479           80 :               if (t != 3)
    4480           32 :                 mio_expr (&n->expr);
    4481              :               break;
    4482            3 :             case 33:
    4483            3 :             case 34:
    4484            3 :             case 35:
    4485            3 :               *ptrs[1] = n = gfc_get_omp_namelist ();
    4486            3 :               n->u.linear.op = (enum gfc_omp_linear_op) (t - 32);
    4487            3 :               t = 4;
    4488            3 :               goto finish_namelist;
    4489              :             }
    4490              :         }
    4491              :     }
    4492              : }
    4493              : 
    4494              : 
    4495              : /* Handle !$omp declare simd.  */
    4496              : 
    4497              : static void
    4498       249915 : mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
    4499              : {
    4500       249915 :   if (iomode == IO_OUTPUT)
    4501              :     {
    4502        27911 :       if (*odsp == NULL)
    4503              :         {
    4504        27831 :           if (ns->omp_declare_variant)
    4505              :             {
    4506           98 :               mio_lparen ();
    4507           98 :               mio_rparen ();
    4508              :             }
    4509        27831 :           return;
    4510              :         }
    4511              :     }
    4512       222004 :   else if (peek_atom () != ATOM_LPAREN)
    4513              :     return;
    4514              : 
    4515          169 :   gfc_omp_declare_simd *ods = *odsp;
    4516              : 
    4517          169 :   mio_lparen ();
    4518          169 :   if (iomode == IO_OUTPUT)
    4519              :     {
    4520           80 :       if (ods->clauses)
    4521           80 :         mio_omp_declare_simd_clauses (&ods->clauses);
    4522              :     }
    4523              :   else
    4524              :     {
    4525           89 :       if (peek_atom () == ATOM_RPAREN)
    4526              :         {
    4527           35 :           mio_rparen ();
    4528           35 :           return;
    4529              :         }
    4530              : 
    4531           54 :       require_atom (ATOM_NAME);
    4532           54 :       *odsp = ods = gfc_get_omp_declare_simd ();
    4533           54 :       ods->where = gfc_current_locus;
    4534           54 :       ods->proc_name = ns->proc_name;
    4535           54 :       mio_omp_declare_simd_clauses (&ods->clauses);
    4536              :     }
    4537              : 
    4538          134 :   mio_omp_declare_simd (ns, &ods->next);
    4539              : 
    4540          134 :   mio_rparen ();
    4541              : }
    4542              : 
    4543              : /* Handle !$omp declare variant.  */
    4544              : 
    4545              : static void
    4546       268700 : mio_omp_declare_variant (gfc_namespace *ns, gfc_omp_declare_variant **odvp)
    4547              : {
    4548       268700 :   if (iomode == IO_OUTPUT)
    4549              :     {
    4550        46707 :       if (*odvp == NULL)
    4551              :         return;
    4552              :     }
    4553       221993 :   else if (peek_atom () != ATOM_LPAREN)
    4554              :     return;
    4555              : 
    4556          157 :   gfc_omp_declare_variant *odv;
    4557              : 
    4558          157 :   mio_lparen ();
    4559          157 :   if (iomode == IO_OUTPUT)
    4560              :     {
    4561          117 :       odv = *odvp;
    4562          117 :       write_atom (ATOM_NAME, "OMP_DECLARE_VARIANT");
    4563          117 :       gfc_symtree *st;
    4564          234 :       st = (odv->base_proc_symtree
    4565          117 :             ? odv->base_proc_symtree
    4566          108 :             : gfc_find_symtree (ns->sym_root, ns->proc_name->name));
    4567          117 :       mio_symtree_ref (&st);
    4568          234 :       st = (st->n.sym->attr.if_source == IFSRC_IFBODY
    4569           31 :             && st->n.sym->formal_ns == ns
    4570          118 :             ? gfc_find_symtree (ns->parent->sym_root,
    4571           30 :                                 odv->variant_proc_symtree->name)
    4572              :             : odv->variant_proc_symtree);
    4573          117 :       mio_symtree_ref (&st);
    4574              : 
    4575          117 :       mio_lparen ();
    4576          117 :       write_atom (ATOM_NAME, "SEL");
    4577          253 :       for (gfc_omp_set_selector *set = odv->set_selectors; set; set = set->next)
    4578              :         {
    4579          136 :           int set_code = set->code;
    4580          136 :           mio_integer (&set_code);
    4581          136 :           mio_lparen ();
    4582          312 :           for (gfc_omp_selector *sel = set->trait_selectors; sel;
    4583          176 :                sel = sel->next)
    4584              :             {
    4585          176 :               int sel_code = sel->code;
    4586          176 :               mio_integer (&sel_code);
    4587          176 :               mio_expr (&sel->score);
    4588          176 :               mio_lparen ();
    4589          232 :               for (gfc_omp_trait_property *prop = sel->properties; prop;
    4590           56 :                    prop = prop->next)
    4591              :                 {
    4592           56 :                   int kind = prop->property_kind;
    4593           56 :                   mio_integer (&kind);
    4594           56 :                   int is_name = prop->is_name;
    4595           56 :                   mio_integer (&is_name);
    4596           56 :                   switch (prop->property_kind)
    4597              :                     {
    4598           11 :                     case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
    4599           11 :                     case OMP_TRAIT_PROPERTY_BOOL_EXPR:
    4600           11 :                       mio_expr (&prop->expr);
    4601           11 :                       break;
    4602            3 :                     case OMP_TRAIT_PROPERTY_ID:
    4603            3 :                       write_atom (ATOM_STRING, prop->name);
    4604            3 :                       break;
    4605           28 :                     case OMP_TRAIT_PROPERTY_NAME_LIST:
    4606           28 :                       if (prop->is_name)
    4607           25 :                         write_atom (ATOM_STRING, prop->name);
    4608              :                       else
    4609            3 :                         mio_expr (&prop->expr);
    4610              :                       break;
    4611           14 :                     case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
    4612           14 :                       {
    4613              :                         /* Currently only declare simd.  */
    4614           14 :                         mio_lparen ();
    4615           14 :                         mio_omp_declare_simd_clauses (&prop->clauses);
    4616           14 :                         mio_rparen ();
    4617              :                       }
    4618           14 :                       break;
    4619            0 :                     default:
    4620            0 :                       gcc_unreachable ();
    4621              :                     }
    4622              :                 }
    4623          176 :               mio_rparen ();
    4624              :             }
    4625          136 :           mio_rparen ();
    4626              :         }
    4627          117 :       mio_rparen ();
    4628              : 
    4629          117 :       mio_lparen ();
    4630          117 :       write_atom (ATOM_NAME, "ADJ");
    4631          225 :       for (gfc_omp_namelist *arg = odv->adjust_args_list; arg; arg = arg->next)
    4632              :         {
    4633          108 :           int need_ptr = arg->u.adj_args.need_ptr;
    4634          108 :           int need_addr = arg->u.adj_args.need_addr;
    4635          108 :           int range_start = arg->u.adj_args.range_start;
    4636          108 :           int omp_num_args_plus = arg->u.adj_args.omp_num_args_plus;
    4637          108 :           int omp_num_args_minus = arg->u.adj_args.omp_num_args_minus;
    4638          108 :           mio_integer (&need_ptr);
    4639          108 :           mio_integer (&need_addr);
    4640          108 :           mio_integer (&range_start);
    4641          108 :           mio_integer (&omp_num_args_plus);
    4642          108 :           mio_integer (&omp_num_args_minus);
    4643          108 :           mio_expr (&arg->expr);
    4644              :         }
    4645          117 :       mio_rparen ();
    4646              : 
    4647          117 :       mio_lparen ();
    4648          117 :       write_atom (ATOM_NAME, "APP");
    4649          155 :       for (gfc_omp_namelist *arg = odv->append_args_list; arg; arg = arg->next)
    4650              :         {
    4651           38 :           int target = arg->u.init.target;
    4652           38 :           int targetsync = arg->u.init.targetsync;
    4653           38 :           mio_integer (&target);
    4654           38 :           mio_integer (&targetsync);
    4655           38 :           mio_integer (&arg->u.init.len);
    4656           38 :           gfc_char_t *p = XALLOCAVEC (gfc_char_t, arg->u.init.len);
    4657          409 :           for (int i = 0; i < arg->u.init.len; i++)
    4658          371 :             p[i] = arg->u2.init_interop[i];
    4659           38 :           mio_allocated_wide_string (p, arg->u.init.len);
    4660              :         }
    4661          117 :       mio_rparen ();
    4662              :     }
    4663              :   else
    4664              :     {
    4665           40 :       if (peek_atom () == ATOM_RPAREN)
    4666              :         {
    4667            0 :           mio_rparen ();
    4668            0 :           return;
    4669              :         }
    4670              : 
    4671           40 :       require_atom (ATOM_NAME);
    4672           40 :       odv = *odvp = gfc_get_omp_declare_variant ();
    4673           40 :       odv->where = gfc_current_locus;
    4674              : 
    4675           40 :       mio_symtree_ref (&odv->base_proc_symtree);
    4676           40 :       mio_symtree_ref (&odv->variant_proc_symtree);
    4677              : 
    4678           40 :       mio_lparen ();
    4679           40 :       require_atom (ATOM_NAME);  /* SEL */
    4680           40 :       gfc_omp_set_selector **set = &odv->set_selectors;
    4681           82 :       while (peek_atom () != ATOM_RPAREN)
    4682              :         {
    4683           42 :           *set = gfc_get_omp_set_selector ();
    4684           42 :           int set_code;
    4685           42 :           mio_integer (&set_code);
    4686           42 :           (*set)->code = (enum omp_tss_code) set_code;
    4687              : 
    4688           42 :           mio_lparen ();
    4689           42 :           gfc_omp_selector **sel = &(*set)->trait_selectors;
    4690           86 :           while (peek_atom () != ATOM_RPAREN)
    4691              :             {
    4692           44 :               *sel = gfc_get_omp_selector ();
    4693           44 :               int sel_code = 0;
    4694           44 :               mio_integer (&sel_code);
    4695           44 :               (*sel)->code = (enum omp_ts_code) sel_code;
    4696           44 :               mio_expr (&(*sel)->score);
    4697              : 
    4698           44 :               mio_lparen ();
    4699           44 :               gfc_omp_trait_property **prop = &(*sel)->properties;
    4700           47 :               while (peek_atom () != ATOM_RPAREN)
    4701              :                 {
    4702            3 :                   *prop = gfc_get_omp_trait_property ();
    4703            3 :                   int kind = 0, is_name = 0;
    4704            3 :                   mio_integer (&kind);
    4705            3 :                   mio_integer (&is_name);
    4706            3 :                   (*prop)->property_kind = (enum omp_tp_type) kind;
    4707            3 :                   (*prop)->is_name = is_name;
    4708            3 :                   switch ((*prop)->property_kind)
    4709              :                     {
    4710            0 :                     case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
    4711            0 :                     case OMP_TRAIT_PROPERTY_BOOL_EXPR:
    4712            0 :                       mio_expr (&(*prop)->expr);
    4713            0 :                       break;
    4714            0 :                     case OMP_TRAIT_PROPERTY_ID:
    4715            0 :                       (*prop)->name = read_string ();
    4716            0 :                       break;
    4717            3 :                     case OMP_TRAIT_PROPERTY_NAME_LIST:
    4718            3 :                       if ((*prop)->is_name)
    4719            2 :                         (*prop)->name = read_string ();
    4720              :                       else
    4721            1 :                         mio_expr (&(*prop)->expr);
    4722              :                       break;
    4723            0 :                     case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
    4724            0 :                       {
    4725              :                         /* Currently only declare simd.  */
    4726            0 :                         mio_lparen ();
    4727            0 :                         mio_omp_declare_simd_clauses (&(*prop)->clauses);
    4728            0 :                         mio_rparen ();
    4729              :                       }
    4730            0 :                       break;
    4731            0 :                     default:
    4732            0 :                       gcc_unreachable ();
    4733              :                     }
    4734            3 :                   prop = &(*prop)->next;
    4735              :                 }
    4736           44 :               mio_rparen ();
    4737           44 :               sel = &(*sel)->next;
    4738              :             }
    4739           42 :           mio_rparen ();
    4740           42 :           set = &(*set)->next;
    4741              :         }
    4742           40 :       mio_rparen ();
    4743              : 
    4744           40 :       mio_lparen ();
    4745           40 :       require_atom (ATOM_NAME);  /* ADJ */
    4746           40 :       gfc_omp_namelist **nl = &odv->adjust_args_list;
    4747          122 :       while (peek_atom () != ATOM_RPAREN)
    4748              :         {
    4749           82 :           *nl = gfc_get_omp_namelist ();
    4750           82 :           (*nl)->where = gfc_current_locus;
    4751           82 :           int need_ptr, need_addr, range_start;
    4752           82 :           int omp_num_args_plus, omp_num_args_minus;
    4753           82 :           mio_integer (&need_ptr);
    4754           82 :           mio_integer (&need_addr);
    4755           82 :           mio_integer (&range_start);
    4756           82 :           mio_integer (&omp_num_args_plus);
    4757           82 :           mio_integer (&omp_num_args_minus);
    4758           82 :           (*nl)->u.adj_args.need_ptr = need_ptr;
    4759           82 :           (*nl)->u.adj_args.need_addr = need_addr;
    4760           82 :           (*nl)->u.adj_args.range_start = range_start;
    4761           82 :           (*nl)->u.adj_args.omp_num_args_plus = omp_num_args_minus;
    4762           82 :           (*nl)->u.adj_args.omp_num_args_plus = omp_num_args_minus;
    4763           82 :           mio_expr (&(*nl)->expr);
    4764           82 :           nl = &(*nl)->next;
    4765              :         }
    4766           40 :       mio_rparen ();
    4767              : 
    4768           40 :       mio_lparen ();
    4769           40 :       require_atom (ATOM_NAME);  /* APP */
    4770           40 :       nl = &odv->append_args_list;
    4771           58 :       while (peek_atom () != ATOM_RPAREN)
    4772              :         {
    4773           18 :           *nl = gfc_get_omp_namelist ();
    4774           18 :           (*nl)->where = gfc_current_locus;
    4775           18 :           int target, targetsync;
    4776           18 :           mio_integer (&target);
    4777           18 :           mio_integer (&targetsync);
    4778           18 :           mio_integer (&(*nl)->u.init.len);
    4779           18 :           (*nl)->u.init.target = target;
    4780           18 :           (*nl)->u.init.targetsync = targetsync;
    4781           18 :           const gfc_char_t *p = XALLOCAVEC (gfc_char_t, (*nl)->u.init.len); // FIXME: memory handling?
    4782           18 :           (*nl)->u2.init_interop = XCNEWVEC (char,  (*nl)->u.init.len);
    4783           18 :           p = mio_allocated_wide_string (NULL, (*nl)->u.init.len);
    4784          101 :           for (int i = 0; i < (*nl)->u.init.len; i++)
    4785           83 :             (*nl)->u2.init_interop[i] = p[i];
    4786           18 :           nl = &(*nl)->next;
    4787              :         }
    4788           40 :       mio_rparen ();
    4789              :     }
    4790              : 
    4791          157 :   mio_omp_declare_variant (ns, &odv->next);
    4792              : 
    4793          157 :   mio_rparen ();
    4794              : }
    4795              : 
    4796              : static const mstring omp_declare_reduction_stmt[] =
    4797              : {
    4798              :     minit ("ASSIGN", 0),
    4799              :     minit ("CALL", 1),
    4800              :     minit (NULL, -1)
    4801              : };
    4802              : 
    4803              : 
    4804              : static void
    4805          280 : mio_omp_udr_expr (gfc_omp_udr *udr, gfc_symbol **sym1, gfc_symbol **sym2,
    4806              :                   gfc_namespace *ns, bool is_initializer)
    4807              : {
    4808          280 :   if (iomode == IO_OUTPUT)
    4809              :     {
    4810          136 :       if ((*sym1)->module == NULL)
    4811              :         {
    4812          100 :           (*sym1)->module = module_name;
    4813          100 :           (*sym2)->module = module_name;
    4814              :         }
    4815          136 :       mio_symbol_ref (sym1);
    4816          136 :       mio_symbol_ref (sym2);
    4817          136 :       if (ns->code->op == EXEC_ASSIGN)
    4818              :         {
    4819           82 :           mio_name (0, omp_declare_reduction_stmt);
    4820           82 :           mio_expr (&ns->code->expr1);
    4821           82 :           mio_expr (&ns->code->expr2);
    4822              :         }
    4823              :       else
    4824              :         {
    4825           54 :           int flag;
    4826           54 :           mio_name (1, omp_declare_reduction_stmt);
    4827           54 :           mio_symtree_ref (&ns->code->symtree);
    4828           54 :           mio_actual_arglist (&ns->code->ext.actual, false);
    4829              : 
    4830           54 :           flag = ns->code->resolved_isym != NULL;
    4831           54 :           mio_integer (&flag);
    4832           54 :           if (flag)
    4833            0 :             write_atom (ATOM_STRING, ns->code->resolved_isym->name);
    4834              :           else
    4835           54 :             mio_symbol_ref (&ns->code->resolved_sym);
    4836              :         }
    4837              :     }
    4838              :   else
    4839              :     {
    4840          144 :       pointer_info *p1 = mio_symbol_ref (sym1);
    4841          144 :       pointer_info *p2 = mio_symbol_ref (sym2);
    4842          144 :       gfc_symbol *sym;
    4843          144 :       gcc_assert (p1->u.rsym.ns == p2->u.rsym.ns);
    4844          144 :       gcc_assert (p1->u.rsym.sym == NULL);
    4845              :       /* Add hidden symbols to the symtree.  */
    4846          144 :       pointer_info *q = get_integer (p1->u.rsym.ns);
    4847          144 :       q->u.pointer = (void *) ns;
    4848          222 :       sym = gfc_new_symbol (is_initializer ? "omp_priv" : "omp_out", ns);
    4849          144 :       sym->ts = udr->ts;
    4850          144 :       sym->module = gfc_get_string ("%s", p1->u.rsym.module);
    4851          144 :       associate_integer_pointer (p1, sym);
    4852          144 :       sym->attr.omp_udr_artificial_var = 1;
    4853          144 :       gcc_assert (p2->u.rsym.sym == NULL);
    4854          222 :       sym = gfc_new_symbol (is_initializer ? "omp_orig" : "omp_in", ns);
    4855          144 :       sym->ts = udr->ts;
    4856          144 :       sym->module = gfc_get_string ("%s", p2->u.rsym.module);
    4857          144 :       associate_integer_pointer (p2, sym);
    4858          144 :       sym->attr.omp_udr_artificial_var = 1;
    4859          144 :       if (mio_name (0, omp_declare_reduction_stmt) == 0)
    4860              :         {
    4861           90 :           ns->code = gfc_get_code (EXEC_ASSIGN);
    4862           90 :           mio_expr (&ns->code->expr1);
    4863           90 :           mio_expr (&ns->code->expr2);
    4864              :         }
    4865              :       else
    4866              :         {
    4867           54 :           int flag;
    4868           54 :           ns->code = gfc_get_code (EXEC_CALL);
    4869           54 :           mio_symtree_ref (&ns->code->symtree);
    4870           54 :           mio_actual_arglist (&ns->code->ext.actual, false);
    4871              : 
    4872           54 :           mio_integer (&flag);
    4873           54 :           if (flag)
    4874              :             {
    4875            0 :               require_atom (ATOM_STRING);
    4876            0 :               ns->code->resolved_isym = gfc_find_subroutine (atom_string);
    4877            0 :               free (atom_string);
    4878              :             }
    4879              :           else
    4880           54 :             mio_symbol_ref (&ns->code->resolved_sym);
    4881              :         }
    4882          144 :       ns->code->loc = gfc_current_locus;
    4883          144 :       ns->omp_udr_ns = 1;
    4884              :     }
    4885          280 : }
    4886              : 
    4887              : 
    4888              : /* Unlike most other routines, the address of the symbol node is already
    4889              :    fixed on input and the name/module has already been filled in.
    4890              :    If you update the symbol format here, don't forget to update read_module
    4891              :    as well (look for "seek to the symbol's component list").   */
    4892              : 
    4893              : static void
    4894      1227033 : mio_symbol (gfc_symbol *sym)
    4895              : {
    4896      1227033 :   int intmod = INTMOD_NONE;
    4897              : 
    4898      1227033 :   mio_lparen ();
    4899              : 
    4900      1227033 :   mio_symbol_attribute (&sym->attr);
    4901              : 
    4902      1227033 :   if (sym->attr.pdt_type)
    4903          525 :     sym->name = gfc_dt_upper_string (sym->name);
    4904              : 
    4905              :   /* Note that components are always saved, even if they are supposed
    4906              :      to be private.  Component access is checked during searching.  */
    4907      1227033 :   mio_component_list (&sym->components, sym->attr.vtype);
    4908      1227033 :   if (sym->components != NULL)
    4909        72943 :     sym->component_access
    4910        72943 :       = MIO_NAME (gfc_access) (sym->component_access, access_types);
    4911              : 
    4912      1227033 :   mio_typespec (&sym->ts);
    4913      1227033 :   if (sym->ts.type == BT_CLASS)
    4914        14830 :     sym->attr.class_ok = 1;
    4915              : 
    4916      1227033 :   if (iomode == IO_OUTPUT)
    4917       233568 :     mio_namespace_ref (&sym->formal_ns);
    4918              :   else
    4919              :     {
    4920       993465 :       mio_namespace_ref (&sym->formal_ns);
    4921       993465 :       if (sym->formal_ns)
    4922       221950 :         sym->formal_ns->proc_name = sym;
    4923              :     }
    4924              : 
    4925              :   /* Save/restore common block links.  */
    4926      1227033 :   mio_symbol_ref (&sym->common_next);
    4927              : 
    4928      1227033 :   mio_formal_arglist (&sym->formal);
    4929              : 
    4930      1227033 :   if (sym->attr.flavor == FL_PARAMETER)
    4931       233961 :     mio_expr (&sym->value);
    4932              : 
    4933      1227033 :   mio_array_spec (&sym->as);
    4934              : 
    4935      1227033 :   mio_symbol_ref (&sym->result);
    4936              : 
    4937      1227033 :   if (sym->attr.cray_pointee)
    4938           26 :     mio_symbol_ref (&sym->cp_pointer);
    4939              : 
    4940              :   /* Load/save the f2k_derived namespace of a derived-type symbol.  */
    4941      1227033 :   mio_full_f2k_derived (sym);
    4942              : 
    4943              :   /* PDT types store the symbol specification list here. */
    4944      1227033 :   mio_actual_arglist (&sym->param_list, true);
    4945              : 
    4946      1227033 :   mio_namelist (sym);
    4947              : 
    4948              :   /* Add the fields that say whether this is from an intrinsic module,
    4949              :      and if so, what symbol it is within the module.  */
    4950              : /*   mio_integer (&(sym->from_intmod)); */
    4951      1227033 :   if (iomode == IO_OUTPUT)
    4952              :     {
    4953       233568 :       intmod = sym->from_intmod;
    4954       233568 :       mio_integer (&intmod);
    4955              :     }
    4956              :   else
    4957              :     {
    4958       993465 :       mio_integer (&intmod);
    4959       993465 :       if (current_intmod)
    4960       317269 :         sym->from_intmod = current_intmod;
    4961              :       else
    4962       676196 :         sym->from_intmod = (intmod_id) intmod;
    4963              :     }
    4964              : 
    4965      1227033 :   mio_integer (&(sym->intmod_sym_id));
    4966              : 
    4967      1227033 :   if (gfc_fl_struct (sym->attr.flavor))
    4968        76208 :     mio_integer (&(sym->hash_value));
    4969              : 
    4970      1227033 :   if (sym->formal_ns
    4971       250288 :       && sym->formal_ns->proc_name == sym
    4972       249781 :       && sym->formal_ns->entries == NULL)
    4973              :     {
    4974       249781 :       mio_omp_declare_simd (sym->formal_ns, &sym->formal_ns->omp_declare_simd);
    4975       249781 :       mio_omp_declare_variant (sym->formal_ns,
    4976       249781 :                                &sym->formal_ns->omp_declare_variant);
    4977              :     }
    4978       205737 :   else if ((iomode == IO_OUTPUT && sym->ns->proc_name == sym)
    4979      1164230 :            || (iomode == IO_INPUT && peek_atom () == ATOM_LPAREN))
    4980        18762 :     mio_omp_declare_variant (sym->ns, &sym->ns->omp_declare_variant);
    4981              : 
    4982      1227033 :   mio_rparen ();
    4983      1227033 : }
    4984              : 
    4985              : 
    4986              : /************************* Top level subroutines *************************/
    4987              : 
    4988              : /* A recursive function to look for a specific symbol by name and by
    4989              :    module.  Whilst several symtrees might point to one symbol, its
    4990              :    is sufficient for the purposes here than one exist.  Note that
    4991              :    generic interfaces are distinguished as are symbols that have been
    4992              :    renamed in another module.  */
    4993              : static gfc_symtree *
    4994     39296547 : find_symbol (gfc_symtree *st, const char *name,
    4995              :              const char *module, int generic)
    4996              : {
    4997     78116051 :   int c;
    4998     78116051 :   gfc_symtree *retval, *s;
    4999              : 
    5000     78116051 :   if (st == NULL || st->n.sym == NULL)
    5001              :     return NULL;
    5002              : 
    5003     38821919 :   c = strcmp (name, st->n.sym->name);
    5004        94113 :   if (c == 0 && st->n.sym->module
    5005        94107 :              && strcmp (module, st->n.sym->module) == 0
    5006     38860122 :              && !check_unique_name (st->name))
    5007              :     {
    5008        38117 :       s = gfc_find_symtree (gfc_current_ns->sym_root, name);
    5009              : 
    5010              :       /* Detect symbols that are renamed by use association in another
    5011              :          module by the absence of a symtree and null attr.use_rename,
    5012              :          since the latter is not transmitted in the module file.  */
    5013        38117 :       if (((!generic && !st->n.sym->attr.generic)
    5014        29401 :                 || (generic && st->n.sym->attr.generic))
    5015         8756 :             && !(s == NULL && !st->n.sym->attr.use_rename))
    5016              :         return st;
    5017              :     }
    5018              : 
    5019     38821325 :   retval = find_symbol (st->left, name, module, generic);
    5020              : 
    5021     38821325 :   if (retval == NULL)
    5022     38819504 :     retval = find_symbol (st->right, name, module, generic);
    5023              : 
    5024              :   return retval;
    5025              : }
    5026              : 
    5027              : 
    5028              : /* Skip a list between balanced left and right parens.
    5029              :    By setting NEST_LEVEL one assumes that a number of NEST_LEVEL opening parens
    5030              :    have been already parsed by hand, and the remaining of the content is to be
    5031              :    skipped here.  The default value is 0 (balanced parens).  */
    5032              : 
    5033              : static void
    5034      1338162 : skip_list (int nest_level = 0)
    5035              : {
    5036      1338162 :   int level;
    5037              : 
    5038      1338162 :   level = nest_level;
    5039     62892632 :   do
    5040              :     {
    5041     62892632 :       switch (parse_atom ())
    5042              :         {
    5043     15562120 :         case ATOM_LPAREN:
    5044     15562120 :           level++;
    5045     15562120 :           break;
    5046              : 
    5047     15578679 :         case ATOM_RPAREN:
    5048     15578679 :           level--;
    5049     15578679 :           break;
    5050              : 
    5051       682110 :         case ATOM_STRING:
    5052       682110 :           free (atom_string);
    5053       682110 :           break;
    5054              : 
    5055              :         case ATOM_NAME:
    5056              :         case ATOM_INTEGER:
    5057              :           break;
    5058              :         }
    5059              :     }
    5060     62892632 :   while (level > 0);
    5061      1338162 : }
    5062              : 
    5063              : 
    5064              : /* Load operator interfaces from the module.  Interfaces are unusual
    5065              :    in that they attach themselves to existing symbols.  */
    5066              : 
    5067              : static void
    5068        13283 : load_operator_interfaces (void)
    5069              : {
    5070        13283 :   const char *p;
    5071              :   /* "module" must be large enough for the case of submodules in which the name
    5072              :      has the form module.submodule */
    5073        13283 :   char name[GFC_MAX_SYMBOL_LEN + 1], module[2 * GFC_MAX_SYMBOL_LEN + 2];
    5074        13283 :   gfc_user_op *uop;
    5075        13283 :   pointer_info *pi = NULL;
    5076        13283 :   int n, i;
    5077              : 
    5078        13283 :   mio_lparen ();
    5079              : 
    5080        26729 :   while (peek_atom () != ATOM_RPAREN)
    5081              :     {
    5082          163 :       mio_lparen ();
    5083              : 
    5084          163 :       mio_internal_string (name);
    5085          163 :       mio_internal_string (module);
    5086              : 
    5087          163 :       n = number_use_names (name, true);
    5088          163 :       n = n ? n : 1;
    5089              : 
    5090          344 :       for (i = 1; i <= n; i++)
    5091              :         {
    5092              :           /* Decide if we need to load this one or not.  */
    5093          181 :           p = find_use_name_n (name, &i, true);
    5094              : 
    5095          181 :           if (p == NULL)
    5096              :             {
    5097           14 :               while (parse_atom () != ATOM_RPAREN);
    5098            7 :               continue;
    5099              :             }
    5100              : 
    5101          174 :           if (i == 1)
    5102              :             {
    5103          156 :               uop = gfc_get_uop (p);
    5104          156 :               pi = mio_interface_rest (&uop->op);
    5105              :             }
    5106              :           else
    5107              :             {
    5108           18 :               if (gfc_find_uop (p, NULL))
    5109            6 :                 continue;
    5110           12 :               uop = gfc_get_uop (p);
    5111           12 :               uop->op = gfc_get_interface ();
    5112           12 :               uop->op->where = gfc_current_locus;
    5113           12 :               add_fixup (pi->integer, &uop->op->sym);
    5114              :             }
    5115              :         }
    5116              :     }
    5117              : 
    5118        13283 :   mio_rparen ();
    5119        13283 : }
    5120              : 
    5121              : 
    5122              : /* Load interfaces from the module.  Interfaces are unusual in that
    5123              :    they attach themselves to existing symbols.  */
    5124              : 
    5125              : static void
    5126        13283 : load_generic_interfaces (void)
    5127              : {
    5128        13283 :   const char *p;
    5129              :   /* "module" must be large enough for the case of submodules in which the name
    5130              :      has the form module.submodule */
    5131        13283 :   char name[GFC_MAX_SYMBOL_LEN + 1], module[2 * GFC_MAX_SYMBOL_LEN + 2];
    5132        13283 :   gfc_symbol *sym;
    5133        13283 :   gfc_interface *generic = NULL, *gen = NULL;
    5134        13283 :   int n, i, renamed;
    5135        13283 :   bool ambiguous_set = false;
    5136              : 
    5137        13283 :   mio_lparen ();
    5138              : 
    5139        81905 :   while (peek_atom () != ATOM_RPAREN)
    5140              :     {
    5141        55339 :       mio_lparen ();
    5142              : 
    5143        55339 :       mio_internal_string (name);
    5144        55339 :       mio_internal_string (module);
    5145              : 
    5146        55339 :       n = number_use_names (name, false);
    5147        55339 :       renamed = n ? 1 : 0;
    5148        54592 :       n = n ? n : 1;
    5149              : 
    5150       110682 :       for (i = 1; i <= n; i++)
    5151              :         {
    5152        55343 :           gfc_symtree *st;
    5153              :           /* Decide if we need to load this one or not.  */
    5154        55343 :           p = find_use_name_n (name, &i, false);
    5155              : 
    5156        55343 :           if (!p || gfc_find_symbol (p, NULL, 0, &sym))
    5157              :             {
    5158              :               /* Skip the specific names for these cases.  */
    5159         9361 :               while (i == 1 && parse_atom () != ATOM_RPAREN);
    5160              : 
    5161         1694 :               continue;
    5162              :             }
    5163              : 
    5164        53649 :           st = find_symbol (gfc_current_ns->sym_root,
    5165              :                             name, module_name, 1);
    5166              : 
    5167              :           /* If the symbol exists already and is being USEd without being
    5168              :              in an ONLY clause, do not load a new symtree(11.3.2).  */
    5169        53649 :           if (!only_flag && st)
    5170           44 :             sym = st->n.sym;
    5171              : 
    5172        53649 :           if (!sym)
    5173              :             {
    5174        27316 :               if (st)
    5175              :                 {
    5176            1 :                   sym = st->n.sym;
    5177            1 :                   if (strcmp (st->name, p) != 0)
    5178              :                     {
    5179            1 :                       st = gfc_new_symtree (&gfc_current_ns->sym_root, p);
    5180            1 :                       st->n.sym = sym;
    5181            1 :                       sym->refs++;
    5182              :                     }
    5183              :                 }
    5184              : 
    5185              :               /* Since we haven't found a valid generic interface, we had
    5186              :                  better make one.  */
    5187        27316 :               if (!sym)
    5188              :                 {
    5189        27315 :                   gfc_get_symbol (p, NULL, &sym);
    5190        27315 :                   sym->name = gfc_get_string ("%s", name);
    5191        27315 :                   sym->module = module_name;
    5192        27315 :                   sym->attr.flavor = FL_PROCEDURE;
    5193        27315 :                   sym->attr.generic = 1;
    5194        27315 :                   sym->attr.use_assoc = 1;
    5195              :                 }
    5196              :             }
    5197              :           else
    5198              :             {
    5199              :               /* Unless sym is a generic interface, this reference
    5200              :                  is ambiguous.  */
    5201        26333 :               if (st == NULL)
    5202        26288 :                 st = gfc_find_symtree (gfc_current_ns->sym_root, p);
    5203              : 
    5204        26333 :               sym = st->n.sym;
    5205              : 
    5206        26333 :               if (st && !sym->attr.generic
    5207        23994 :                      && !st->ambiguous
    5208        23994 :                      && sym->module
    5209        23993 :                      && strcmp (module, sym->module))
    5210              :                 {
    5211            1 :                   ambiguous_set = true;
    5212            1 :                   st->ambiguous = 1;
    5213              :                 }
    5214              :             }
    5215              : 
    5216        53649 :           sym->attr.use_only = only_flag;
    5217        53649 :           sym->attr.use_rename = renamed;
    5218              : 
    5219        53649 :           if (i == 1)
    5220              :             {
    5221        53645 :               mio_interface_rest (&sym->generic);
    5222        53645 :               generic = sym->generic;
    5223              :             }
    5224            4 :           else if (!sym->generic)
    5225              :             {
    5226            0 :               sym->generic = generic;
    5227            0 :               sym->attr.generic_copy = 1;
    5228              :             }
    5229              : 
    5230              :           /* If a procedure that is not generic has generic interfaces
    5231              :              that include itself, it is generic! We need to take care
    5232              :              to retain symbols ambiguous that were already so.  */
    5233        53649 :           if (sym->attr.use_assoc
    5234        29656 :                 && !sym->attr.generic
    5235            2 :                 && sym->attr.flavor == FL_PROCEDURE)
    5236              :             {
    5237            4 :               for (gen = generic; gen; gen = gen->next)
    5238              :                 {
    5239            3 :                   if (gen->sym == sym)
    5240              :                     {
    5241            1 :                       sym->attr.generic = 1;
    5242            1 :                       if (ambiguous_set)
    5243            0 :                         st->ambiguous = 0;
    5244              :                       break;
    5245              :                     }
    5246              :                 }
    5247              :             }
    5248              : 
    5249              :         }
    5250              :     }
    5251              : 
    5252        13283 :   mio_rparen ();
    5253        13283 : }
    5254              : 
    5255              : 
    5256              : /* Load common blocks.  */
    5257              : 
    5258              : static void
    5259        13283 : load_commons (void)
    5260              : {
    5261        13283 :   char name[GFC_MAX_SYMBOL_LEN + 1];
    5262        13283 :   gfc_common_head *p;
    5263              : 
    5264        13283 :   mio_lparen ();
    5265              : 
    5266        26736 :   while (peek_atom () != ATOM_RPAREN)
    5267              :     {
    5268          170 :       int flags = 0;
    5269          170 :       char* label;
    5270          170 :       mio_lparen ();
    5271          170 :       mio_internal_string (name);
    5272              : 
    5273          170 :       p = gfc_get_common (name, 1);
    5274              : 
    5275          170 :       mio_symbol_ref (&p->head);
    5276          170 :       mio_integer (&flags);
    5277          170 :       if (flags & 1)
    5278            0 :         p->saved = 1;
    5279          170 :       if (flags & 2)
    5280            0 :         p->threadprivate = 1;
    5281          170 :       p->omp_device_type = (gfc_omp_device_type) ((flags >> 2) & 3);
    5282          170 :       if ((flags >> 4) & 1)
    5283            0 :         p->omp_groupprivate = 1;
    5284          170 :       p->use_assoc = 1;
    5285              : 
    5286              :       /* Get whether this was a bind(c) common or not.  */
    5287          170 :       mio_integer (&p->is_bind_c);
    5288              :       /* Get the binding label.  */
    5289          170 :       label = read_string ();
    5290          170 :       if (strlen (label))
    5291           22 :         p->binding_label = IDENTIFIER_POINTER (get_identifier (label));
    5292          170 :       XDELETEVEC (label);
    5293              : 
    5294          170 :       mio_rparen ();
    5295              :     }
    5296              : 
    5297        13283 :   mio_rparen ();
    5298        13283 : }
    5299              : 
    5300              : 
    5301              : /* Load equivalences.  The flag in_load_equiv informs mio_expr_ref of this
    5302              :    so that unused variables are not loaded and so that the expression can
    5303              :    be safely freed.  */
    5304              : 
    5305              : static void
    5306        13283 : load_equiv (void)
    5307              : {
    5308        13283 :   gfc_equiv *head, *tail, *end, *eq, *equiv;
    5309        13283 :   bool duplicate;
    5310              : 
    5311        13283 :   mio_lparen ();
    5312        13283 :   in_load_equiv = true;
    5313              : 
    5314        13283 :   end = gfc_current_ns->equiv;
    5315        13289 :   while (end != NULL && end->next != NULL)
    5316              :     end = end->next;
    5317              : 
    5318        13416 :   while (peek_atom () != ATOM_RPAREN) {
    5319          133 :     mio_lparen ();
    5320          133 :     head = tail = NULL;
    5321              : 
    5322          532 :     while(peek_atom () != ATOM_RPAREN)
    5323              :       {
    5324          266 :         if (head == NULL)
    5325          133 :           head = tail = gfc_get_equiv ();
    5326              :         else
    5327              :           {
    5328          133 :             tail->eq = gfc_get_equiv ();
    5329          133 :             tail = tail->eq;
    5330              :           }
    5331              : 
    5332          266 :         mio_pool_string (&tail->module);
    5333          266 :         mio_expr (&tail->expr);
    5334              :       }
    5335              : 
    5336              :     /* Check for duplicate equivalences being loaded from different modules */
    5337          133 :     duplicate = false;
    5338          192 :     for (equiv = gfc_current_ns->equiv; equiv; equiv = equiv->next)
    5339              :       {
    5340           65 :         if (equiv->module && head->module
    5341           65 :             && strcmp (equiv->module, head->module) == 0)
    5342              :           {
    5343              :             duplicate = true;
    5344              :             break;
    5345              :           }
    5346              :       }
    5347              : 
    5348          133 :     if (duplicate)
    5349              :       {
    5350           18 :         for (eq = head; eq; eq = head)
    5351              :           {
    5352           12 :             head = eq->eq;
    5353           12 :             gfc_free_expr (eq->expr);
    5354           12 :             free (eq);
    5355              :           }
    5356              :       }
    5357              : 
    5358          133 :     if (end == NULL)
    5359           80 :       gfc_current_ns->equiv = head;
    5360              :     else
    5361           53 :       end->next = head;
    5362              : 
    5363          133 :     if (head != NULL)
    5364          127 :       end = head;
    5365              : 
    5366          133 :     mio_rparen ();
    5367              :   }
    5368              : 
    5369        13283 :   mio_rparen ();
    5370        13283 :   in_load_equiv = false;
    5371        13283 : }
    5372              : 
    5373              : 
    5374              : /* This function loads OpenMP user defined reductions.  */
    5375              : static void
    5376        13283 : load_omp_udrs (void)
    5377              : {
    5378        13283 :   mio_lparen ();
    5379        26648 :   while (peek_atom () != ATOM_RPAREN)
    5380              :     {
    5381           82 :       const char *name = NULL, *newname;
    5382           82 :       char *altname;
    5383           82 :       gfc_typespec ts;
    5384           82 :       gfc_symtree *st;
    5385           82 :       gfc_omp_reduction_op rop = OMP_REDUCTION_USER;
    5386              : 
    5387           82 :       mio_lparen ();
    5388           82 :       mio_pool_string (&name);
    5389           82 :       gfc_clear_ts (&ts);
    5390           82 :       mio_typespec (&ts);
    5391           82 :       if (startswith (name, "operator "))
    5392              :         {
    5393           32 :           const char *p = name + sizeof ("operator ") - 1;
    5394           32 :           if (strcmp (p, "+") == 0)
    5395              :             rop = OMP_REDUCTION_PLUS;
    5396            0 :           else if (strcmp (p, "*") == 0)
    5397              :             rop = OMP_REDUCTION_TIMES;
    5398            0 :           else if (strcmp (p, "-") == 0)
    5399              :             rop = OMP_REDUCTION_MINUS;
    5400            0 :           else if (strcmp (p, ".and.") == 0)
    5401              :             rop = OMP_REDUCTION_AND;
    5402            0 :           else if (strcmp (p, ".or.") == 0)
    5403              :             rop = OMP_REDUCTION_OR;
    5404            0 :           else if (strcmp (p, ".eqv.") == 0)
    5405              :             rop = OMP_REDUCTION_EQV;
    5406            0 :           else if (strcmp (p, ".neqv.") == 0)
    5407              :             rop = OMP_REDUCTION_NEQV;
    5408              :         }
    5409           50 :       altname = NULL;
    5410           50 :       if (rop == OMP_REDUCTION_USER && name[0] == '.')
    5411              :         {
    5412           50 :           size_t len = strlen (name + 1);
    5413           50 :           altname = XALLOCAVEC (char, len);
    5414           50 :           gcc_assert (name[len] == '.');
    5415           50 :           memcpy (altname, name + 1, len - 1);
    5416           50 :           altname[len - 1] = '\0';
    5417              :         }
    5418           82 :       newname = name;
    5419           82 :       if (rop == OMP_REDUCTION_USER)
    5420          100 :         newname = find_use_name (altname ? altname : name, !!altname);
    5421           38 :       else if (only_flag && find_use_operator ((gfc_intrinsic_op) rop) == NULL)
    5422              :         newname = NULL;
    5423           82 :       if (newname == NULL)
    5424              :         {
    5425            0 :           skip_list (1);
    5426            4 :           continue;
    5427              :         }
    5428           82 :       if (altname && newname != altname)
    5429              :         {
    5430           18 :           size_t len = strlen (newname);
    5431           18 :           altname = XALLOCAVEC (char, len + 3);
    5432           18 :           altname[0] = '.';
    5433           18 :           memcpy (altname + 1, newname, len);
    5434           18 :           altname[len + 1] = '.';
    5435           18 :           altname[len + 2] = '\0';
    5436           18 :           name = gfc_get_string ("%s", altname);
    5437              :         }
    5438           82 :       st = gfc_find_symtree (gfc_current_ns->omp_udr_root, name);
    5439           82 :       gfc_omp_udr *udr = gfc_omp_udr_find (st, &ts);
    5440           82 :       if (udr)
    5441              :         {
    5442            4 :           require_atom (ATOM_INTEGER);
    5443            4 :           pointer_info *p = get_integer (atom_int);
    5444            4 :           if (strcmp (p->u.rsym.module, udr->omp_out->module))
    5445              :             {
    5446            4 :               gfc_error ("Ambiguous !$OMP DECLARE REDUCTION from "
    5447              :                          "module %s at %L",
    5448              :                          p->u.rsym.module, &gfc_current_locus);
    5449            4 :               gfc_error ("Previous !$OMP DECLARE REDUCTION from module "
    5450              :                          "%s at %L",
    5451            4 :                          udr->omp_out->module, &udr->where);
    5452              :             }
    5453            4 :           skip_list (1);
    5454            4 :           continue;
    5455            4 :         }
    5456           78 :       udr = gfc_get_omp_udr ();
    5457           78 :       udr->name = name;
    5458           78 :       udr->rop = rop;
    5459           78 :       udr->ts = ts;
    5460           78 :       udr->where = gfc_current_locus;
    5461           78 :       udr->combiner_ns = gfc_get_namespace (gfc_current_ns, 1);
    5462           78 :       udr->combiner_ns->proc_name = gfc_current_ns->proc_name;
    5463           78 :       mio_omp_udr_expr (udr, &udr->omp_out, &udr->omp_in, udr->combiner_ns,
    5464              :                         false);
    5465           78 :       if (peek_atom () != ATOM_RPAREN)
    5466              :         {
    5467           66 :           udr->initializer_ns = gfc_get_namespace (gfc_current_ns, 1);
    5468           66 :           udr->initializer_ns->proc_name = gfc_current_ns->proc_name;
    5469           66 :           mio_omp_udr_expr (udr, &udr->omp_priv, &udr->omp_orig,
    5470              :                             udr->initializer_ns, true);
    5471              :         }
    5472           78 :       if (st)
    5473              :         {
    5474            0 :           udr->next = st->n.omp_udr;
    5475            0 :           st->n.omp_udr = udr;
    5476              :         }
    5477              :       else
    5478              :         {
    5479           78 :           st = gfc_new_symtree (&gfc_current_ns->omp_udr_root, name);
    5480           78 :           st->n.omp_udr = udr;
    5481              :         }
    5482           78 :       mio_rparen ();
    5483              :     }
    5484        13283 :   mio_rparen ();
    5485        13283 : }
    5486              : 
    5487              : 
    5488              : /* Recursive function to traverse the pointer_info tree and load a
    5489              :    needed symbol.  We return nonzero if we load a symbol and stop the
    5490              :    traversal, because the act of loading can alter the tree.  */
    5491              : 
    5492              : static int
    5493      9647786 : load_needed (pointer_info *p)
    5494              : {
    5495      9647786 :   gfc_namespace *ns;
    5496      9647786 :   pointer_info *q;
    5497      9647786 :   gfc_symbol *sym;
    5498      9647786 :   int rv;
    5499              : 
    5500      9647786 :   rv = 0;
    5501      9647786 :   if (p == NULL)
    5502              :     return rv;
    5503              : 
    5504      4805335 :   rv |= load_needed (p->left);
    5505      4805335 :   rv |= load_needed (p->right);
    5506              : 
    5507      4805335 :   if (p->type != P_SYMBOL || p->u.rsym.state != NEEDED)
    5508              :     return rv;
    5509              : 
    5510       993465 :   p->u.rsym.state = USED;
    5511              : 
    5512       993465 :   set_module_locus (&p->u.rsym.where);
    5513              : 
    5514       993465 :   sym = p->u.rsym.sym;
    5515       993465 :   if (sym == NULL)
    5516              :     {
    5517       597949 :       q = get_integer (p->u.rsym.ns);
    5518              : 
    5519       597949 :       ns = (gfc_namespace *) q->u.pointer;
    5520       597949 :       if (ns == NULL)
    5521              :         {
    5522              :           /* Create an interface namespace if necessary.  These are
    5523              :              the namespaces that hold the formal parameters of module
    5524              :              procedures.  */
    5525              : 
    5526        21313 :           ns = gfc_get_namespace (NULL, 0);
    5527        21313 :           associate_integer_pointer (q, ns);
    5528              :         }
    5529              : 
    5530              :       /* Use the module sym as 'proc_name' so that gfc_get_symbol_decl
    5531              :          doesn't go pear-shaped if the symbol is used.  */
    5532       597949 :       if (!ns->proc_name)
    5533        29968 :         gfc_find_symbol (p->u.rsym.module, gfc_current_ns,
    5534              :                                  1, &ns->proc_name);
    5535              : 
    5536       597949 :       sym = gfc_new_symbol (p->u.rsym.true_name, ns);
    5537       597949 :       sym->name = gfc_dt_lower_string (p->u.rsym.true_name);
    5538       597949 :       sym->module = gfc_get_string ("%s", p->u.rsym.module);
    5539       597949 :       if (p->u.rsym.binding_label)
    5540           19 :         sym->binding_label = IDENTIFIER_POINTER (get_identifier
    5541              :                                                  (p->u.rsym.binding_label));
    5542              : 
    5543       597949 :       associate_integer_pointer (p, sym);
    5544              :     }
    5545              : 
    5546       993465 :   mio_symbol (sym);
    5547       993465 :   sym->attr.use_assoc = 1;
    5548              : 
    5549              :   /* Unliked derived types, a STRUCTURE may share names with other symbols.
    5550              :      We greedily converted the symbol name to lowercase before we knew its
    5551              :      type, so now we must fix it. */
    5552       993465 :   if (sym->attr.flavor == FL_STRUCT)
    5553           60 :     sym->name = gfc_dt_upper_string (sym->name);
    5554              : 
    5555              :   /* Mark as only or rename for later diagnosis for explicitly imported
    5556              :      but not used warnings; don't mark internal symbols such as __vtab,
    5557              :      __def_init etc. Only mark them if they have been explicitly loaded.  */
    5558              : 
    5559       993465 :   if (only_flag && sym->name[0] != '_' && sym->name[1] != '_')
    5560              :     {
    5561        11945 :       gfc_use_rename *u;
    5562              : 
    5563              :       /* Search the use/rename list for the variable; if the variable is
    5564              :          found, mark it.  */
    5565        29326 :       for (u = gfc_rename_list; u; u = u->next)
    5566              :         {
    5567        20308 :           if (strcmp (u->use_name, sym->name) == 0)
    5568              :             {
    5569         2927 :               sym->attr.use_only = 1;
    5570         2927 :               break;
    5571              :             }
    5572              :         }
    5573              :     }
    5574              : 
    5575       993465 :   if (p->u.rsym.renamed)
    5576         3296 :     sym->attr.use_rename = 1;
    5577              : 
    5578              :   return 1;
    5579              : }
    5580              : 
    5581              : 
    5582              : /* Recursive function for cleaning up things after a module has been read.  */
    5583              : 
    5584              : static void
    5585      3274163 : read_cleanup (pointer_info *p)
    5586              : {
    5587      3274163 :   gfc_symtree *st;
    5588      3274163 :   pointer_info *q;
    5589              : 
    5590      3274163 :   if (p == NULL)
    5591              :     return;
    5592              : 
    5593      1630440 :   read_cleanup (p->left);
    5594      1630440 :   read_cleanup (p->right);
    5595              : 
    5596      1630440 :   if (p->type == P_SYMBOL && p->u.rsym.state == USED && !p->u.rsym.referenced)
    5597              :     {
    5598       645253 :       gfc_namespace *ns;
    5599              :       /* Add hidden symbols to the symtree.  */
    5600       645253 :       q = get_integer (p->u.rsym.ns);
    5601       645253 :       ns = (gfc_namespace *) q->u.pointer;
    5602              : 
    5603       645253 :       if (!p->u.rsym.sym->attr.vtype
    5604       644155 :             && !p->u.rsym.sym->attr.vtab)
    5605       643367 :         st = gfc_get_unique_symtree (ns);
    5606              :       else
    5607              :         {
    5608              :           /* There is no reason to use 'unique_symtrees' for vtabs or
    5609              :              vtypes - their name is fine for a symtree and reduces the
    5610              :              namespace pollution.  */
    5611         1886 :           st = gfc_find_symtree (ns->sym_root, p->u.rsym.sym->name);
    5612         1886 :           if (!st)
    5613          298 :             st = gfc_new_symtree (&ns->sym_root, p->u.rsym.sym->name);
    5614              :         }
    5615              : 
    5616       645253 :       st->n.sym = p->u.rsym.sym;
    5617       645253 :       st->n.sym->refs++;
    5618              : 
    5619              :       /* Fixup any symtree references.  */
    5620       645253 :       p->u.rsym.symtree = st;
    5621       645253 :       resolve_fixups (p->u.rsym.stfixup, st);
    5622       645253 :       p->u.rsym.stfixup = NULL;
    5623              :     }
    5624              : 
    5625              :   /* Free unused symbols.  */
    5626      1630440 :   if (p->type == P_SYMBOL && p->u.rsym.state == UNUSED)
    5627       151880 :     gfc_free_symbol (p->u.rsym.sym);
    5628              : }
    5629              : 
    5630              : 
    5631              : /* It is not quite enough to check for ambiguity in the symbols by
    5632              :    the loaded symbol and the new symbol not being identical.  */
    5633              : static bool
    5634        42693 : check_for_ambiguous (gfc_symtree *st, pointer_info *info)
    5635              : {
    5636        42693 :   gfc_symbol *rsym;
    5637        42693 :   module_locus locus;
    5638        42693 :   symbol_attribute attr;
    5639        42693 :   gfc_symbol *st_sym;
    5640              : 
    5641        42693 :   if (gfc_current_ns->proc_name && st->name == gfc_current_ns->proc_name->name)
    5642              :     {
    5643            6 :       gfc_error ("%qs of module %qs, imported at %C, is also the name of the "
    5644              :                  "current program unit", st->name, module_name);
    5645            6 :       return true;
    5646              :     }
    5647              : 
    5648        42687 :   st_sym = st->n.sym;
    5649        42687 :   rsym = info->u.rsym.sym;
    5650        42687 :   if (st_sym == rsym)
    5651              :     return false;
    5652              : 
    5653          609 :   if (st_sym->attr.vtab || st_sym->attr.vtype)
    5654              :     return false;
    5655              : 
    5656              :   /* If the existing symbol is generic from a different module and
    5657              :      the new symbol is generic there can be no ambiguity.  */
    5658          421 :   if (st_sym->attr.generic
    5659           20 :         && st_sym->module
    5660           20 :         && st_sym->module != module_name)
    5661              :     {
    5662              :       /* The new symbol's attributes have not yet been read.  Since
    5663              :          we need attr.generic, read it directly.  */
    5664           20 :       get_module_locus (&locus);
    5665           20 :       set_module_locus (&info->u.rsym.where);
    5666           20 :       mio_lparen ();
    5667           20 :       attr.generic = 0;
    5668           20 :       mio_symbol_attribute (&attr);
    5669           20 :       set_module_locus (&locus);
    5670           20 :       if (attr.generic)
    5671              :         return false;
    5672              :     }
    5673              : 
    5674              :   return true;
    5675              : }
    5676              : 
    5677              : 
    5678              : /* Read a module file.  */
    5679              : 
    5680              : static void
    5681        13283 : read_module (void)
    5682              : {
    5683        13283 :   module_locus operator_interfaces, user_operators, omp_udrs;
    5684        13283 :   const char *p;
    5685        13283 :   char name[GFC_MAX_SYMBOL_LEN + 1];
    5686        13283 :   int i;
    5687              :   /* Workaround -Wmaybe-uninitialized false positive during
    5688              :      profiledbootstrap by initializing them.  */
    5689        13283 :   int ambiguous = 0, j, nuse, symbol = 0;
    5690        13283 :   pointer_info *info, *q;
    5691        13283 :   gfc_use_rename *u = NULL;
    5692        13283 :   gfc_symtree *st;
    5693        13283 :   gfc_symbol *sym;
    5694              : 
    5695        13283 :   get_module_locus (&operator_interfaces);  /* Skip these for now.  */
    5696        13283 :   skip_list ();
    5697              : 
    5698        13283 :   get_module_locus (&user_operators);
    5699        13283 :   skip_list ();
    5700        13283 :   skip_list ();
    5701              : 
    5702              :   /* Skip commons and equivalences for now.  */
    5703        13283 :   skip_list ();
    5704        13283 :   skip_list ();
    5705              : 
    5706              :   /* Skip OpenMP UDRs.  */
    5707        13283 :   get_module_locus (&omp_udrs);
    5708        13283 :   skip_list ();
    5709              : 
    5710        13283 :   mio_lparen ();
    5711              : 
    5712              :   /* Create the fixup nodes for all the symbols.  */
    5713              : 
    5714      1220615 :   while (peek_atom () != ATOM_RPAREN)
    5715              :     {
    5716      1194049 :       char* bind_label;
    5717      1194049 :       require_atom (ATOM_INTEGER);
    5718      1194049 :       info = get_integer (atom_int);
    5719              : 
    5720      1194049 :       info->type = P_SYMBOL;
    5721      1194049 :       info->u.rsym.state = UNUSED;
    5722              : 
    5723      1194049 :       info->u.rsym.true_name = read_string ();
    5724      1194049 :       info->u.rsym.module = read_string ();
    5725      1194049 :       bind_label = read_string ();
    5726      1194049 :       if (strlen (bind_label))
    5727        32341 :         info->u.rsym.binding_label = bind_label;
    5728              :       else
    5729      1161708 :         XDELETEVEC (bind_label);
    5730              : 
    5731      1194049 :       require_atom (ATOM_INTEGER);
    5732      1194049 :       info->u.rsym.ns = atom_int;
    5733              : 
    5734      1194049 :       get_module_locus (&info->u.rsym.where);
    5735              : 
    5736              :       /* See if the symbol has already been loaded by a previous module.
    5737              :          If so, we reference the existing symbol and prevent it from
    5738              :          being loaded again.  This should not happen if the symbol being
    5739              :          read is an index for an assumed shape dummy array (ns != 1).  */
    5740              : 
    5741      1194049 :       sym = find_true_name (info->u.rsym.true_name, info->u.rsym.module);
    5742              : 
    5743      1194049 :       if (sym == NULL
    5744        48729 :           || (sym->attr.flavor == FL_VARIABLE && info->u.rsym.ns !=1))
    5745              :         {
    5746      1145345 :           skip_list ();
    5747      1145345 :           continue;
    5748              :         }
    5749              : 
    5750        48704 :       info->u.rsym.state = USED;
    5751        48704 :       info->u.rsym.sym = sym;
    5752              :       /* The current symbol has already been loaded, so we can avoid loading
    5753              :          it again.  However, if it is a derived type, some of its components
    5754              :          can be used in expressions in the module.  To avoid the module loading
    5755              :          failing, we need to associate the module's component pointer indexes
    5756              :          with the existing symbol's component pointers.  */
    5757        48704 :       if (gfc_fl_struct (sym->attr.flavor))
    5758              :         {
    5759         4626 :           gfc_component *c;
    5760              : 
    5761              :           /* First seek to the symbol's component list.  */
    5762         4626 :           mio_lparen (); /* symbol opening.  */
    5763         4626 :           skip_list (); /* skip symbol attribute.  */
    5764              : 
    5765         4626 :           mio_lparen (); /* component list opening.  */
    5766        16555 :           for (c = sym->components; c; c = c->next)
    5767              :             {
    5768        11929 :               pointer_info *p;
    5769        11929 :               const char *comp_name = NULL;
    5770        11929 :               int n = 0;
    5771              : 
    5772        11929 :               mio_lparen (); /* component opening.  */
    5773        11929 :               mio_integer (&n);
    5774        11929 :               p = get_integer (n);
    5775        11929 :               if (p->u.pointer == NULL)
    5776        11929 :                 associate_integer_pointer (p, c);
    5777        11929 :               mio_pool_string (&comp_name);
    5778        11929 :               if (comp_name != c->name)
    5779              :                 {
    5780            0 :                   gfc_fatal_error ("Mismatch in components of derived type "
    5781              :                                    "%qs from %qs at %C: expecting %qs, "
    5782              :                                    "but got %qs", sym->name, sym->module,
    5783              :                                    c->name, comp_name);
    5784              :                 }
    5785        11929 :               skip_list (1); /* component end.  */
    5786              :             }
    5787         4626 :           mio_rparen (); /* component list closing.  */
    5788              : 
    5789         4626 :           skip_list (1); /* symbol end.  */
    5790         4626 :         }
    5791              :       else
    5792        44078 :         skip_list ();
    5793              : 
    5794              :       /* Some symbols do not have a namespace (eg. formal arguments),
    5795              :          so the automatic "unique symtree" mechanism must be suppressed
    5796              :          by marking them as referenced.  */
    5797        48704 :       q = get_integer (info->u.rsym.ns);
    5798        48704 :       if (q->u.pointer == NULL)
    5799              :         {
    5800         1573 :           info->u.rsym.referenced = 1;
    5801         1573 :           continue;
    5802              :         }
    5803              :     }
    5804              : 
    5805        13283 :   mio_rparen ();
    5806              : 
    5807              :   /* Parse the symtree lists.  This lets us mark which symbols need to
    5808              :      be loaded.  Renaming is also done at this point by replacing the
    5809              :      symtree name.  */
    5810              : 
    5811        13283 :   mio_lparen ();
    5812              : 
    5813       514371 :   while (peek_atom () != ATOM_RPAREN)
    5814              :     {
    5815       487805 :       mio_internal_string (name);
    5816       487805 :       mio_integer (&ambiguous);
    5817       487805 :       mio_integer (&symbol);
    5818              : 
    5819       487805 :       info = get_integer (symbol);
    5820              : 
    5821              :       /* See how many use names there are.  If none, go through the start
    5822              :          of the loop at least once.  */
    5823       487805 :       nuse = number_use_names (name, false);
    5824       487805 :       info->u.rsym.renamed = nuse ? 1 : 0;
    5825              : 
    5826         3319 :       if (nuse == 0)
    5827       484486 :         nuse = 1;
    5828              : 
    5829       975645 :       for (j = 1; j <= nuse; j++)
    5830              :         {
    5831              :           /* Get the jth local name for this symbol.  */
    5832       487840 :           p = find_use_name_n (name, &j, false);
    5833              : 
    5834       487840 :           if (p == NULL && strcmp (name, module_name) == 0)
    5835              :             p = name;
    5836              : 
    5837              :           /* Exception: Always import vtabs & vtypes.  */
    5838        51532 :           if (p == NULL && name[0] == '_'
    5839         3263 :               && (startswith (name, "__vtab_")
    5840         2151 :                   || startswith (name, "__vtype_")))
    5841              :             p = name;
    5842              : 
    5843              :           /* Include pdt_types if their associated pdt_template is in a
    5844              :              USE, ONLY list.  */
    5845        49308 :           if (p == NULL && name[0] == 'P'
    5846           46 :               && startswith (name, PDT_PREFIX)
    5847       485632 :               && module_list)
    5848              :             {
    5849           32 :               gfc_use_list *ml = module_list;
    5850           32 :               for (; ml; ml = ml->next)
    5851           16 :                 if (ml->rename
    5852           16 :                     && !strncmp (&name[PDT_PREFIX_LEN],
    5853              :                                  ml->rename->use_name,
    5854           16 :                                  strlen (ml->rename->use_name)))
    5855           16 :                   p = name;
    5856              :             }
    5857              : 
    5858              :           /* Skip symtree nodes not in an ONLY clause, unless there
    5859              :              is an existing symtree loaded from another USE statement.  */
    5860       487840 :           if (p == NULL)
    5861              :             {
    5862        49292 :               st = gfc_find_symtree (gfc_current_ns->sym_root, name);
    5863        49292 :               if (st != NULL
    5864          559 :                   && strcmp (st->n.sym->name, info->u.rsym.true_name) == 0
    5865          501 :                   && st->n.sym->module != NULL
    5866          199 :                   && strcmp (st->n.sym->module, info->u.rsym.module) == 0)
    5867              :                 {
    5868          191 :                   info->u.rsym.symtree = st;
    5869          191 :                   info->u.rsym.sym = st->n.sym;
    5870              :                 }
    5871        49292 :               continue;
    5872              :             }
    5873              : 
    5874              :           /* If a symbol of the same name and module exists already,
    5875              :              this symbol, which is not in an ONLY clause, must not be
    5876              :              added to the namespace(11.3.2).  Note that find_symbol
    5877              :              only returns the first occurrence that it finds.  */
    5878       431898 :           if (!only_flag && !info->u.rsym.renamed
    5879       431553 :                 && strcmp (name, module_name) != 0
    5880       860121 :                 && find_symbol (gfc_current_ns->sym_root, name,
    5881              :                                 module_name, 0))
    5882          548 :             continue;
    5883              : 
    5884       438000 :           st = gfc_find_symtree (gfc_current_ns->sym_root, p);
    5885              : 
    5886       438000 :           if (st != NULL
    5887        42730 :               && !(st->n.sym && st->n.sym->attr.used_in_submodule))
    5888              :             {
    5889              :               /* Check for ambiguous symbols.  */
    5890        42693 :               if (check_for_ambiguous (st, info))
    5891          408 :                 st->ambiguous = 1;
    5892              :               else
    5893        42285 :                 info->u.rsym.symtree = st;
    5894              :             }
    5895              :           else
    5896              :             {
    5897       395307 :               if (st)
    5898              :                 {
    5899              :                   /* This symbol is host associated from a module in a
    5900              :                      submodule.  Hide it with a unique symtree.  */
    5901           37 :                   gfc_symtree *s = gfc_get_unique_symtree (gfc_current_ns);
    5902           37 :                   s->n.sym = st->n.sym;
    5903           37 :                   st->n.sym = NULL;
    5904              :                 }
    5905              :               else
    5906              :                 {
    5907              :                   /* Create a symtree node in the current namespace for this
    5908              :                      symbol.  */
    5909       395270 :                   st = check_unique_name (p)
    5910       395270 :                        ? gfc_get_unique_symtree (gfc_current_ns)
    5911       395270 :                        : gfc_new_symtree (&gfc_current_ns->sym_root, p);
    5912       395270 :                   st->ambiguous = ambiguous;
    5913              :                 }
    5914              : 
    5915       395307 :               sym = info->u.rsym.sym;
    5916              : 
    5917              :               /* Create a symbol node if it doesn't already exist.  */
    5918       395307 :               if (sym == NULL)
    5919              :                 {
    5920       395153 :                   info->u.rsym.sym = gfc_new_symbol (info->u.rsym.true_name,
    5921              :                                                      gfc_current_ns);
    5922       395153 :                   info->u.rsym.sym->name = gfc_dt_lower_string (info->u.rsym.true_name);
    5923       395153 :                   sym = info->u.rsym.sym;
    5924       395153 :                   sym->module = gfc_get_string ("%s", info->u.rsym.module);
    5925              : 
    5926       395153 :                   if (info->u.rsym.binding_label)
    5927              :                     {
    5928        21702 :                       tree id = get_identifier (info->u.rsym.binding_label);
    5929        21702 :                       sym->binding_label = IDENTIFIER_POINTER (id);
    5930              :                     }
    5931              :                 }
    5932              : 
    5933       395307 :               st->n.sym = sym;
    5934       395307 :               st->n.sym->refs++;
    5935              : 
    5936       395307 :               if (strcmp (name, p) != 0)
    5937          520 :                 sym->attr.use_rename = 1;
    5938              : 
    5939       395307 :               if (name[0] != '_'
    5940       395307 :                   || (!startswith (name, "__vtab_")
    5941        30213 :                       && !startswith (name, "__vtype_")))
    5942       366439 :                 sym->attr.use_only = only_flag;
    5943              : 
    5944              :               /* Store the symtree pointing to this symbol.  */
    5945       395307 :               info->u.rsym.symtree = st;
    5946              : 
    5947       395307 :               if (info->u.rsym.state == UNUSED)
    5948       395153 :                 info->u.rsym.state = NEEDED;
    5949       395307 :               info->u.rsym.referenced = 1;
    5950              :             }
    5951              :         }
    5952              :     }
    5953              : 
    5954        13283 :   mio_rparen ();
    5955              : 
    5956              :   /* Load intrinsic operator interfaces.  */
    5957        13283 :   set_module_locus (&operator_interfaces);
    5958        13283 :   mio_lparen ();
    5959              : 
    5960       385207 :   for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
    5961              :     {
    5962       371924 :       gfc_use_rename *u = NULL, *v = NULL;
    5963       371924 :       int j = i;
    5964              : 
    5965       371924 :       if (i == INTRINSIC_USER)
    5966        13283 :         continue;
    5967              : 
    5968       358641 :       if (only_flag)
    5969              :         {
    5970        48006 :           u = find_use_operator ((gfc_intrinsic_op) i);
    5971              : 
    5972              :           /* F2018:10.1.5.5.1 requires same interpretation of old and new-style
    5973              :              relational operators.  Special handling for USE, ONLY.  */
    5974        48006 :           switch (i)
    5975              :             {
    5976              :             case INTRINSIC_EQ:
    5977              :               j = INTRINSIC_EQ_OS;
    5978              :               break;
    5979              :             case INTRINSIC_EQ_OS:
    5980              :               j = INTRINSIC_EQ;
    5981              :               break;
    5982              :             case INTRINSIC_NE:
    5983              :               j = INTRINSIC_NE_OS;
    5984              :               break;
    5985              :             case INTRINSIC_NE_OS:
    5986              :               j = INTRINSIC_NE;
    5987              :               break;
    5988              :             case INTRINSIC_GT:
    5989              :               j = INTRINSIC_GT_OS;
    5990              :               break;
    5991              :             case INTRINSIC_GT_OS:
    5992              :               j = INTRINSIC_GT;
    5993              :               break;
    5994              :             case INTRINSIC_GE:
    5995              :               j = INTRINSIC_GE_OS;
    5996              :               break;
    5997              :             case INTRINSIC_GE_OS:
    5998              :               j = INTRINSIC_GE;
    5999              :               break;
    6000              :             case INTRINSIC_LT:
    6001              :               j = INTRINSIC_LT_OS;
    6002              :               break;
    6003              :             case INTRINSIC_LT_OS:
    6004              :               j = INTRINSIC_LT;
    6005              :               break;
    6006              :             case INTRINSIC_LE:
    6007              :               j = INTRINSIC_LE_OS;
    6008              :               break;
    6009              :             case INTRINSIC_LE_OS:
    6010              :               j = INTRINSIC_LE;
    6011              :               break;
    6012              :             default:
    6013              :               break;
    6014              :             }
    6015              : 
    6016              :           if (j != i)
    6017        21336 :             v = find_use_operator ((gfc_intrinsic_op) j);
    6018              : 
    6019        48006 :           if (u == NULL && v == NULL)
    6020              :             {
    6021        47856 :               skip_list ();
    6022        47856 :               continue;
    6023              :             }
    6024              : 
    6025          150 :           if (u)
    6026          113 :             u->found = 1;
    6027          150 :           if (v)
    6028           89 :             v->found = 1;
    6029              :         }
    6030              : 
    6031       310785 :       mio_interface (&gfc_current_ns->op[i]);
    6032       310785 :       if (!gfc_current_ns->op[i] && !gfc_current_ns->op[j])
    6033              :         {
    6034       309105 :           if (u)
    6035           15 :             u->found = 0;
    6036       309105 :           if (v)
    6037           26 :             v->found = 0;
    6038              :         }
    6039              :     }
    6040              : 
    6041        13283 :   mio_rparen ();
    6042              : 
    6043              :   /* Load generic and user operator interfaces.  These must follow the
    6044              :      loading of symtree because otherwise symbols can be marked as
    6045              :      ambiguous.  */
    6046              : 
    6047        13283 :   set_module_locus (&user_operators);
    6048              : 
    6049        13283 :   load_operator_interfaces ();
    6050        13283 :   load_generic_interfaces ();
    6051              : 
    6052        13283 :   load_commons ();
    6053        13283 :   load_equiv ();
    6054              : 
    6055              :   /* Load OpenMP user defined reductions.  */
    6056        13283 :   set_module_locus (&omp_udrs);
    6057        13283 :   load_omp_udrs ();
    6058              : 
    6059              :   /* At this point, we read those symbols that are needed but haven't
    6060              :      been loaded yet.  If one symbol requires another, the other gets
    6061              :      marked as NEEDED if its previous state was UNUSED.  */
    6062              : 
    6063        50399 :   while (load_needed (pi_root));
    6064              : 
    6065              :   /* Make sure all elements of the rename-list were found in the module.  */
    6066              : 
    6067        16194 :   for (u = gfc_rename_list; u; u = u->next)
    6068              :     {
    6069         2911 :       if (u->found)
    6070         2903 :         continue;
    6071              : 
    6072            8 :       if (u->op == INTRINSIC_NONE)
    6073              :         {
    6074            3 :           gfc_error ("Symbol %qs referenced at %L not found in module %qs",
    6075            3 :                      u->use_name, &u->where, module_name);
    6076            3 :           continue;
    6077              :         }
    6078              : 
    6079            5 :       if (u->op == INTRINSIC_USER)
    6080              :         {
    6081            2 :           gfc_error ("User operator %qs referenced at %L not found "
    6082            2 :                      "in module %qs", u->use_name, &u->where, module_name);
    6083            2 :           continue;
    6084              :         }
    6085              : 
    6086            3 :       gfc_error ("Intrinsic operator %qs referenced at %L not found "
    6087              :                  "in module %qs", gfc_op2string (u->op), &u->where,
    6088              :                  module_name);
    6089              :     }
    6090              : 
    6091              :   /* Clean up symbol nodes that were never loaded, create references
    6092              :      to hidden symbols.  */
    6093              : 
    6094        13283 :   read_cleanup (pi_root);
    6095        13283 : }
    6096              : 
    6097              : 
    6098              : /* Given an access type that is specific to an entity and the default
    6099              :    access, return nonzero if the entity is publicly accessible.  If the
    6100              :    element is declared as PUBLIC, then it is public; if declared
    6101              :    PRIVATE, then private, and otherwise it is public unless the default
    6102              :    access in this context has been declared PRIVATE.  */
    6103              : 
    6104              : static bool dump_smod = false;
    6105              : 
    6106              : static bool
    6107      1019817 : check_access (gfc_access specific_access, gfc_access default_access)
    6108              : {
    6109      1019817 :   if (dump_smod)
    6110              :     return true;
    6111              : 
    6112       998168 :   if (specific_access == ACCESS_PUBLIC)
    6113              :     return true;
    6114       968709 :   if (specific_access == ACCESS_PRIVATE)
    6115              :     return false;
    6116              : 
    6117       966402 :   if (flag_module_private)
    6118           91 :     return default_access == ACCESS_PUBLIC;
    6119              :   else
    6120       966311 :     return default_access != ACCESS_PRIVATE;
    6121              : }
    6122              : 
    6123              : 
    6124              : bool
    6125       848421 : gfc_check_symbol_access (gfc_symbol *sym)
    6126              : {
    6127       848421 :   if (sym->attr.vtab || sym->attr.vtype)
    6128              :     return true;
    6129              :   else
    6130       760961 :     return check_access (sym->attr.access, sym->ns->default_access);
    6131              : }
    6132              : 
    6133              : 
    6134              : /* A structure to remember which commons we've already written.  */
    6135              : 
    6136              : struct written_common
    6137              : {
    6138              :   BBT_HEADER(written_common);
    6139              :   const char *name, *label;
    6140              : };
    6141              : 
    6142              : static struct written_common *written_commons = NULL;
    6143              : 
    6144              : /* Comparison function used for balancing the binary tree.  */
    6145              : 
    6146              : static int
    6147          145 : compare_written_commons (void *a1, void *b1)
    6148              : {
    6149          145 :   const char *aname = ((struct written_common *) a1)->name;
    6150          145 :   const char *alabel = ((struct written_common *) a1)->label;
    6151          145 :   const char *bname = ((struct written_common *) b1)->name;
    6152          145 :   const char *blabel = ((struct written_common *) b1)->label;
    6153          145 :   int c = strcmp (aname, bname);
    6154              : 
    6155          145 :   return (c != 0 ? c : strcmp (alabel, blabel));
    6156              : }
    6157              : 
    6158              : /* Free a list of written commons.  */
    6159              : 
    6160              : static void
    6161         9649 : free_written_common (struct written_common *w)
    6162              : {
    6163         9649 :   if (!w)
    6164              :     return;
    6165              : 
    6166          211 :   if (w->left)
    6167           21 :     free_written_common (w->left);
    6168          211 :   if (w->right)
    6169           48 :     free_written_common (w->right);
    6170              : 
    6171          211 :   free (w);
    6172              : }
    6173              : 
    6174              : /* Write a common block to the module -- recursive helper function.  */
    6175              : 
    6176              : static void
    6177        20100 : write_common_0 (gfc_symtree *st, bool this_module)
    6178              : {
    6179        20100 :   gfc_common_head *p;
    6180        20100 :   const char * name;
    6181        20100 :   int flags;
    6182        20100 :   const char *label;
    6183        20100 :   struct written_common *w;
    6184        20100 :   bool write_me = true;
    6185              : 
    6186        20100 :   if (st == NULL)
    6187        19630 :     return;
    6188              : 
    6189          470 :   write_common_0 (st->left, this_module);
    6190              : 
    6191              :   /* We will write out the binding label, or "" if no label given.  */
    6192          470 :   name = st->n.common->name;
    6193          470 :   p = st->n.common;
    6194          470 :   label = (p->is_bind_c && p->binding_label) ? p->binding_label : "";
    6195              : 
    6196              :   /* Check if we've already output this common.  */
    6197          470 :   w = written_commons;
    6198         1012 :   while (w)
    6199              :     {
    6200          542 :       int c = strcmp (name, w->name);
    6201          542 :       c = (c != 0 ? c : strcmp (label, w->label));
    6202          206 :       if (c == 0)
    6203              :         write_me = false;
    6204              : 
    6205          542 :       w = (c < 0) ? w->left : w->right;
    6206              :     }
    6207              : 
    6208          470 :   if (this_module && p->use_assoc)
    6209              :     write_me = false;
    6210              : 
    6211          417 :   if (write_me)
    6212              :     {
    6213              :       /* Write the common to the module.  */
    6214          211 :       mio_lparen ();
    6215          211 :       mio_pool_string (&name);
    6216              : 
    6217          211 :       mio_symbol_ref (&p->head);
    6218          211 :       flags = p->saved ? 1 : 0;
    6219          211 :       if (p->threadprivate)
    6220            0 :         flags |= 2;
    6221          211 :       flags |= p->omp_device_type << 2;
    6222          211 :       flags |= p->omp_groupprivate << 4;
    6223          211 :       mio_integer (&flags);
    6224              : 
    6225              :       /* Write out whether the common block is bind(c) or not.  */
    6226          211 :       mio_integer (&(p->is_bind_c));
    6227              : 
    6228          211 :       mio_pool_string (&label);
    6229          211 :       mio_rparen ();
    6230              : 
    6231              :       /* Record that we have written this common.  */
    6232          211 :       w = XCNEW (struct written_common);
    6233          211 :       w->name = p->name;
    6234          211 :       w->label = label;
    6235          211 :       gfc_insert_bbt (&written_commons, w, compare_written_commons);
    6236              :     }
    6237              : 
    6238          470 :   write_common_0 (st->right, this_module);
    6239              : }
    6240              : 
    6241              : 
    6242              : /* Write a common, by initializing the list of written commons, calling
    6243              :    the recursive function write_common_0() and cleaning up afterwards.  */
    6244              : 
    6245              : static void
    6246         9580 : write_common (gfc_symtree *st)
    6247              : {
    6248         9580 :   written_commons = NULL;
    6249         9580 :   write_common_0 (st, true);
    6250         9580 :   write_common_0 (st, false);
    6251         9580 :   free_written_common (written_commons);
    6252         9580 :   written_commons = NULL;
    6253         9580 : }
    6254              : 
    6255              : 
    6256              : /* Write the blank common block to the module.  */
    6257              : 
    6258              : static void
    6259         9580 : write_blank_common (void)
    6260              : {
    6261         9580 :   const char * name = BLANK_COMMON_NAME;
    6262         9580 :   int saved;
    6263              :   /* TODO: Blank commons are not bind(c).  The F2003 standard probably says
    6264              :      this, but it hasn't been checked.  Just making it so for now.  */
    6265         9580 :   int is_bind_c = 0;
    6266              : 
    6267         9580 :   if (gfc_current_ns->blank_common.head == NULL)
    6268         9573 :     return;
    6269              : 
    6270            7 :   mio_lparen ();
    6271              : 
    6272            7 :   mio_pool_string (&name);
    6273              : 
    6274            7 :   mio_symbol_ref (&gfc_current_ns->blank_common.head);
    6275            7 :   saved = gfc_current_ns->blank_common.saved;
    6276            7 :   mio_integer (&saved);
    6277              : 
    6278              :   /* Write out whether the common block is bind(c) or not.  */
    6279            7 :   mio_integer (&is_bind_c);
    6280              : 
    6281              :   /* Write out an empty binding label.  */
    6282            7 :   write_atom (ATOM_STRING, "");
    6283              : 
    6284            7 :   mio_rparen ();
    6285              : }
    6286              : 
    6287              : 
    6288              : /* Write equivalences to the module.  */
    6289              : 
    6290              : static void
    6291         9580 : write_equiv (void)
    6292              : {
    6293         9580 :   gfc_equiv *eq, *e;
    6294         9580 :   int num;
    6295              : 
    6296         9580 :   num = 0;
    6297         9662 :   for (eq = gfc_current_ns->equiv; eq; eq = eq->next)
    6298              :     {
    6299           82 :       mio_lparen ();
    6300              : 
    6301          328 :       for (e = eq; e; e = e->eq)
    6302              :         {
    6303          164 :           if (e->module == NULL)
    6304          142 :             e->module = gfc_get_string ("%s.eq.%d", module_name, num);
    6305          164 :           mio_allocated_string (e->module);
    6306          164 :           mio_expr (&e->expr);
    6307              :         }
    6308              : 
    6309           82 :       num++;
    6310           82 :       mio_rparen ();
    6311              :     }
    6312         9580 : }
    6313              : 
    6314              : 
    6315              : /* Write a symbol to the module.  */
    6316              : 
    6317              : static void
    6318       233568 : write_symbol (int n, gfc_symbol *sym)
    6319              : {
    6320       233568 :   const char *label;
    6321              : 
    6322       233568 :   if (sym->attr.flavor == FL_UNKNOWN || sym->attr.flavor == FL_LABEL)
    6323            0 :     gfc_internal_error ("write_symbol(): bad module symbol %qs", sym->name);
    6324              : 
    6325       233568 :   mio_integer (&n);
    6326              : 
    6327       233568 :   if (gfc_fl_struct (sym->attr.flavor))
    6328              :     {
    6329        26225 :       const char *name;
    6330        26225 :       name = gfc_dt_upper_string (sym->name);
    6331        26225 :       mio_pool_string (&name);
    6332        26225 :     }
    6333              :   else
    6334       207343 :     mio_pool_string (&sym->name);
    6335              : 
    6336       233568 :   mio_pool_string (&sym->module);
    6337       233568 :   if ((sym->attr.is_bind_c || sym->attr.is_iso_c) && sym->binding_label)
    6338              :     {
    6339         2690 :       label = sym->binding_label;
    6340         2690 :       mio_pool_string (&label);
    6341              :     }
    6342              :   else
    6343       230878 :     write_atom (ATOM_STRING, "");
    6344              : 
    6345       233568 :   mio_pointer_ref (&sym->ns);
    6346              : 
    6347       233568 :   mio_symbol (sym);
    6348       233568 :   write_char ('\n');
    6349       233568 : }
    6350              : 
    6351              : 
    6352              : /* Recursive traversal function to write the initial set of symbols to
    6353              :    the module.  We check to see if the symbol should be written
    6354              :    according to the access specification.  */
    6355              : 
    6356              : static void
    6357       159915 : write_symbol0 (gfc_symtree *st)
    6358              : {
    6359       310250 :   gfc_symbol *sym;
    6360       310250 :   pointer_info *p;
    6361       310250 :   bool dont_write = false;
    6362              : 
    6363       310250 :   if (st == NULL)
    6364       159915 :     return;
    6365              : 
    6366       150335 :   write_symbol0 (st->left);
    6367              : 
    6368       150335 :   sym = st->n.sym;
    6369       150335 :   if (sym->module == NULL)
    6370        69575 :     sym->module = module_name;
    6371              : 
    6372       150335 :   if (sym->attr.flavor == FL_PROCEDURE && sym->attr.generic
    6373        11496 :       && !sym->attr.subroutine && !sym->attr.function)
    6374       150335 :     dont_write = true;
    6375              : 
    6376       150335 :   if (!gfc_check_symbol_access (sym))
    6377              :     dont_write = true;
    6378              : 
    6379       132024 :   if (!dont_write)
    6380              :     {
    6381       130555 :       p = get_pointer (sym);
    6382       130555 :       if (p->type == P_UNKNOWN)
    6383        99486 :         p->type = P_SYMBOL;
    6384              : 
    6385       130555 :       if (p->u.wsym.state != WRITTEN)
    6386              :         {
    6387       127705 :           write_symbol (p->integer, sym);
    6388       127705 :           p->u.wsym.state = WRITTEN;
    6389              :         }
    6390              :     }
    6391              : 
    6392       150335 :   write_symbol0 (st->right);
    6393              : }
    6394              : 
    6395              : 
    6396              : static void
    6397           94 : write_omp_udr (gfc_omp_udr *udr)
    6398              : {
    6399           94 :   switch (udr->rop)
    6400              :     {
    6401           65 :     case OMP_REDUCTION_USER:
    6402              :       /* Non-operators can't be used outside of the module.  */
    6403           65 :       if (udr->name[0] != '.')
    6404              :         return;
    6405              :       else
    6406              :         {
    6407           47 :           gfc_symtree *st;
    6408           47 :           size_t len = strlen (udr->name + 1);
    6409           47 :           char *name = XALLOCAVEC (char, len);
    6410           47 :           memcpy (name, udr->name, len - 1);
    6411           47 :           name[len - 1] = '\0';
    6412           47 :           st = gfc_find_symtree (gfc_current_ns->uop_root, name);
    6413              :           /* If corresponding user operator is private, don't write
    6414              :              the UDR.  */
    6415           47 :           if (st != NULL)
    6416              :             {
    6417            0 :               gfc_user_op *uop = st->n.uop;
    6418            0 :               if (!check_access (uop->access, uop->ns->default_access))
    6419              :                 return;
    6420              :             }
    6421              :         }
    6422              :       break;
    6423           29 :     case OMP_REDUCTION_PLUS:
    6424           29 :     case OMP_REDUCTION_MINUS:
    6425           29 :     case OMP_REDUCTION_TIMES:
    6426           29 :     case OMP_REDUCTION_AND:
    6427           29 :     case OMP_REDUCTION_OR:
    6428           29 :     case OMP_REDUCTION_EQV:
    6429           29 :     case OMP_REDUCTION_NEQV:
    6430              :       /* If corresponding operator is private, don't write the UDR.  */
    6431           29 :       if (!check_access (gfc_current_ns->operator_access[udr->rop],
    6432              :                          gfc_current_ns->default_access))
    6433              :         return;
    6434              :       break;
    6435              :     default:
    6436              :       break;
    6437              :     }
    6438           75 :   if (udr->ts.type == BT_DERIVED || udr->ts.type == BT_CLASS)
    6439              :     {
    6440              :       /* If derived type is private, don't write the UDR.  */
    6441           39 :       if (!gfc_check_symbol_access (udr->ts.u.derived))
    6442              :         return;
    6443              :     }
    6444              : 
    6445           74 :   mio_lparen ();
    6446           74 :   mio_pool_string (&udr->name);
    6447           74 :   mio_typespec (&udr->ts);
    6448           74 :   mio_omp_udr_expr (udr, &udr->omp_out, &udr->omp_in, udr->combiner_ns, false);
    6449           74 :   if (udr->initializer_ns)
    6450           62 :     mio_omp_udr_expr (udr, &udr->omp_priv, &udr->omp_orig,
    6451              :                       udr->initializer_ns, true);
    6452           74 :   mio_rparen ();
    6453              : }
    6454              : 
    6455              : 
    6456              : static void
    6457         9674 : write_omp_udrs (gfc_symtree *st)
    6458              : {
    6459         9768 :   if (st == NULL)
    6460         9674 :     return;
    6461              : 
    6462           94 :   write_omp_udrs (st->left);
    6463           94 :   gfc_omp_udr *udr;
    6464          188 :   for (udr = st->n.omp_udr; udr; udr = udr->next)
    6465           94 :     write_omp_udr (udr);
    6466           94 :   write_omp_udrs (st->right);
    6467              : }
    6468              : 
    6469              : 
    6470              : /* Type for the temporary tree used when writing secondary symbols.  */
    6471              : 
    6472              : struct sorted_pointer_info
    6473              : {
    6474              :   BBT_HEADER (sorted_pointer_info);
    6475              : 
    6476              :   pointer_info *p;
    6477              : };
    6478              : 
    6479              : #define gfc_get_sorted_pointer_info() XCNEW (sorted_pointer_info)
    6480              : 
    6481              : /* Recursively traverse the temporary tree, free its contents.  */
    6482              : 
    6483              : static void
    6484       226458 : free_sorted_pointer_info_tree (sorted_pointer_info *p)
    6485              : {
    6486       226458 :   if (!p)
    6487              :     return;
    6488              : 
    6489       105863 :   free_sorted_pointer_info_tree (p->left);
    6490       105863 :   free_sorted_pointer_info_tree (p->right);
    6491              : 
    6492       105863 :   free (p);
    6493              : }
    6494              : 
    6495              : /* Comparison function for the temporary tree.  */
    6496              : 
    6497              : static int
    6498       363863 : compare_sorted_pointer_info (void *_spi1, void *_spi2)
    6499              : {
    6500       363863 :   sorted_pointer_info *spi1, *spi2;
    6501       363863 :   spi1 = (sorted_pointer_info *)_spi1;
    6502       363863 :   spi2 = (sorted_pointer_info *)_spi2;
    6503              : 
    6504       363863 :   if (spi1->p->integer < spi2->p->integer)
    6505              :     return -1;
    6506       206308 :   if (spi1->p->integer > spi2->p->integer)
    6507       206308 :     return 1;
    6508              :   return 0;
    6509              : }
    6510              : 
    6511              : 
    6512              : /* Finds the symbols that need to be written and collects them in the
    6513              :    sorted_pi tree so that they can be traversed in an order
    6514              :    independent of memory addresses.  */
    6515              : 
    6516              : static void
    6517      1189761 : find_symbols_to_write(sorted_pointer_info **tree, pointer_info *p)
    6518              : {
    6519      2355210 :   if (!p)
    6520      1189761 :     return;
    6521              : 
    6522      1165449 :   if (p->type == P_SYMBOL && p->u.wsym.state == NEEDS_WRITE)
    6523              :     {
    6524       105863 :       sorted_pointer_info *sp = gfc_get_sorted_pointer_info();
    6525       105863 :       sp->p = p;
    6526              : 
    6527       105863 :       gfc_insert_bbt (tree, sp, compare_sorted_pointer_info);
    6528              :    }
    6529              : 
    6530      1165449 :   find_symbols_to_write (tree, p->left);
    6531      1165449 :   find_symbols_to_write (tree, p->right);
    6532              : }
    6533              : 
    6534              : 
    6535              : /* Recursive function that traverses the tree of symbols that need to be
    6536              :    written and writes them in order.  */
    6537              : 
    6538              : static void
    6539       120595 : write_symbol1_recursion (sorted_pointer_info *sp)
    6540              : {
    6541       226458 :   if (!sp)
    6542       120595 :     return;
    6543              : 
    6544       105863 :   write_symbol1_recursion (sp->left);
    6545              : 
    6546       105863 :   pointer_info *p1 = sp->p;
    6547       105863 :   gcc_assert (p1->type == P_SYMBOL && p1->u.wsym.state == NEEDS_WRITE);
    6548              : 
    6549       105863 :   p1->u.wsym.state = WRITTEN;
    6550       105863 :   write_symbol (p1->integer, p1->u.wsym.sym);
    6551       105863 :   p1->u.wsym.sym->attr.public_used = 1;
    6552              : 
    6553       105863 :   write_symbol1_recursion (sp->right);
    6554              : }
    6555              : 
    6556              : 
    6557              : /* Write the secondary set of symbols to the module file.  These are
    6558              :    symbols that were not public yet are needed by the public symbols
    6559              :    or another dependent symbol.  The act of writing a symbol can add
    6560              :    symbols to the pointer_info tree, so we return nonzero if a symbol
    6561              :    was written and pass that information upwards.  The caller will
    6562              :    then call this function again until nothing was written.  It uses
    6563              :    the utility functions and a temporary tree to ensure a reproducible
    6564              :    ordering of the symbol output and thus the module file.  */
    6565              : 
    6566              : static int
    6567        24312 : write_symbol1 (pointer_info *p)
    6568              : {
    6569        24312 :   if (!p)
    6570              :     return 0;
    6571              : 
    6572              :   /* Put symbols that need to be written into a tree sorted on the
    6573              :      integer field.  */
    6574              : 
    6575        24312 :   sorted_pointer_info *spi_root = NULL;
    6576        24312 :   find_symbols_to_write (&spi_root, p);
    6577              : 
    6578              :   /* No symbols to write, return.  */
    6579        24312 :   if (!spi_root)
    6580              :     return 0;
    6581              : 
    6582              :   /* Otherwise, write and free the tree again.  */
    6583        14732 :   write_symbol1_recursion (spi_root);
    6584        14732 :   free_sorted_pointer_info_tree (spi_root);
    6585              : 
    6586        14732 :   return 1;
    6587              : }
    6588              : 
    6589              : 
    6590              : /* Write operator interfaces associated with a symbol.  */
    6591              : 
    6592              : static void
    6593          167 : write_operator (gfc_user_op *uop)
    6594              : {
    6595          167 :   static char nullstring[] = "";
    6596          167 :   const char *p = nullstring;
    6597              : 
    6598          167 :   if (uop->op == NULL || !check_access (uop->access, uop->ns->default_access))
    6599            1 :     return;
    6600              : 
    6601          166 :   mio_symbol_interface (&uop->name, &p, &uop->op);
    6602              : }
    6603              : 
    6604              : 
    6605              : /* Write generic interfaces from the namespace sym_root.  */
    6606              : 
    6607              : static void
    6608       159915 : write_generic (gfc_symtree *st)
    6609              : {
    6610       310250 :   gfc_symbol *sym;
    6611              : 
    6612       310250 :   if (st == NULL)
    6613       159915 :     return;
    6614              : 
    6615       150335 :   write_generic (st->left);
    6616              : 
    6617       150335 :   sym = st->n.sym;
    6618       150335 :   if (sym && !check_unique_name (st->name)
    6619       293356 :       && sym->generic && gfc_check_symbol_access (sym))
    6620              :     {
    6621        10485 :       if (!sym->module)
    6622         6900 :         sym->module = module_name;
    6623              : 
    6624        10485 :       mio_symbol_interface (&st->name, &sym->module, &sym->generic);
    6625              :     }
    6626              : 
    6627       150335 :   write_generic (st->right);
    6628              : }
    6629              : 
    6630              : 
    6631              : static void
    6632       150336 : write_symtree (gfc_symtree *st)
    6633              : {
    6634       150336 :   gfc_symbol *sym;
    6635       150336 :   pointer_info *p;
    6636              : 
    6637       150336 :   sym = st->n.sym;
    6638              : 
    6639              :   /* A symbol in an interface body must not be visible in the
    6640              :      module file.  */
    6641       150336 :   if (sym->ns != gfc_current_ns
    6642          448 :         && sym->ns->proc_name
    6643          448 :         && sym->ns->proc_name->attr.if_source == IFSRC_IFBODY)
    6644              :     return;
    6645              : 
    6646       150336 :   if (!gfc_check_symbol_access (sym)
    6647       150336 :       || (sym->attr.flavor == FL_PROCEDURE && sym->attr.generic
    6648        10609 :           && !sym->attr.subroutine && !sym->attr.function))
    6649              :     return;
    6650              : 
    6651       130555 :   if (check_unique_name (st->name))
    6652              :     return;
    6653              : 
    6654              :   /* From F2003 onwards, intrinsic procedures are no longer subject to
    6655              :      the restriction, "that an elemental intrinsic function here be of
    6656              :      type integer or character and each argument must be an initialization
    6657              :      expr of type integer or character" is lifted so that intrinsic
    6658              :      procedures can be over-ridden. This requires that the intrinsic
    6659              :      symbol not appear in the module file, thereby preventing ambiguity
    6660              :      when USEd.  */
    6661       124201 :   if (strcmp (sym->module, "(intrinsic)") == 0
    6662         2026 :       && (gfc_option.allow_std & GFC_STD_F2003))
    6663              :     return;
    6664              : 
    6665       122176 :   p = find_pointer (sym);
    6666       122176 :   if (p == NULL)
    6667            0 :     gfc_internal_error ("write_symtree(): Symbol not written");
    6668              : 
    6669       122176 :   mio_pool_string (&st->name);
    6670       122176 :   mio_integer (&st->ambiguous);
    6671       122176 :   mio_hwi (&p->integer);
    6672              : }
    6673              : 
    6674              : 
    6675              : static void
    6676         9580 : write_module (void)
    6677              : {
    6678         9580 :   int i;
    6679              : 
    6680              :   /* Initialize the column counter. */
    6681         9580 :   module_column = 1;
    6682              : 
    6683              :   /* Write the operator interfaces.  */
    6684         9580 :   mio_lparen ();
    6685              : 
    6686       287400 :   for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
    6687              :     {
    6688       268240 :       if (i == INTRINSIC_USER)
    6689         9580 :         continue;
    6690              : 
    6691       517320 :       mio_interface (check_access (gfc_current_ns->operator_access[i],
    6692              :                                    gfc_current_ns->default_access)
    6693              :                      ? &gfc_current_ns->op[i] : NULL);
    6694              :     }
    6695              : 
    6696         9580 :   mio_rparen ();
    6697         9580 :   write_char ('\n');
    6698         9580 :   write_char ('\n');
    6699              : 
    6700         9580 :   mio_lparen ();
    6701         9580 :   gfc_traverse_user_op (gfc_current_ns, write_operator);
    6702         9580 :   mio_rparen ();
    6703         9580 :   write_char ('\n');
    6704         9580 :   write_char ('\n');
    6705              : 
    6706         9580 :   mio_lparen ();
    6707         9580 :   write_generic (gfc_current_ns->sym_root);
    6708         9580 :   mio_rparen ();
    6709         9580 :   write_char ('\n');
    6710         9580 :   write_char ('\n');
    6711              : 
    6712         9580 :   mio_lparen ();
    6713         9580 :   write_blank_common ();
    6714         9580 :   write_common (gfc_current_ns->common_root);
    6715         9580 :   mio_rparen ();
    6716         9580 :   write_char ('\n');
    6717         9580 :   write_char ('\n');
    6718              : 
    6719         9580 :   mio_lparen ();
    6720         9580 :   write_equiv ();
    6721         9580 :   mio_rparen ();
    6722         9580 :   write_char ('\n');
    6723         9580 :   write_char ('\n');
    6724              : 
    6725         9580 :   mio_lparen ();
    6726         9580 :   write_omp_udrs (gfc_current_ns->omp_udr_root);
    6727         9580 :   mio_rparen ();
    6728         9580 :   write_char ('\n');
    6729         9580 :   write_char ('\n');
    6730              : 
    6731              :   /* Write symbol information.  First we traverse all symbols in the
    6732              :      primary namespace, writing those that need to be written.
    6733              :      Sometimes writing one symbol will cause another to need to be
    6734              :      written.  A list of these symbols ends up on the write stack, and
    6735              :      we end by popping the bottom of the stack and writing the symbol
    6736              :      until the stack is empty.  */
    6737              : 
    6738         9580 :   mio_lparen ();
    6739              : 
    6740         9580 :   write_symbol0 (gfc_current_ns->sym_root);
    6741        33892 :   while (write_symbol1 (pi_root))
    6742              :     /* Nothing.  */;
    6743              : 
    6744         9580 :   mio_rparen ();
    6745              : 
    6746         9580 :   write_char ('\n');
    6747         9580 :   write_char ('\n');
    6748              : 
    6749         9580 :   mio_lparen ();
    6750         9580 :   gfc_traverse_symtree (gfc_current_ns->sym_root, write_symtree);
    6751         9580 :   mio_rparen ();
    6752         9580 : }
    6753              : 
    6754              : 
    6755              : /* Read a CRC32 sum from the gzip trailer of a module file.  Returns
    6756              :    true on success, false on failure.  */
    6757              : 
    6758              : static bool
    6759        19160 : read_crc32_from_module_file (const char* filename, uLong* crc)
    6760              : {
    6761        19160 :   FILE *file;
    6762        19160 :   char buf[4];
    6763        19160 :   unsigned int val;
    6764              : 
    6765              :   /* Open the file in binary mode.  */
    6766        19160 :   if ((file = fopen (filename, "rb")) == NULL)
    6767              :     return false;
    6768              : 
    6769              :   /* The gzip crc32 value is found in the [END-8, END-4] bytes of the
    6770              :      file. See RFC 1952.  */
    6771         9772 :   if (fseek (file, -8, SEEK_END) != 0)
    6772              :     {
    6773            0 :       fclose (file);
    6774            0 :       return false;
    6775              :     }
    6776              : 
    6777              :   /* Read the CRC32.  */
    6778         9772 :   if (fread (buf, 1, 4, file) != 4)
    6779              :     {
    6780            0 :       fclose (file);
    6781            0 :       return false;
    6782              :     }
    6783              : 
    6784              :   /* Close the file.  */
    6785         9772 :   fclose (file);
    6786              : 
    6787         9772 :   val = (buf[0] & 0xFF) + ((buf[1] & 0xFF) << 8) + ((buf[2] & 0xFF) << 16)
    6788         9772 :     + ((buf[3] & 0xFF) << 24);
    6789         9772 :   *crc = val;
    6790              : 
    6791              :   /* For debugging, the CRC value printed in hexadecimal should match
    6792              :      the CRC printed by "zcat -l -v filename".
    6793              :      printf("CRC of file %s is %x\n", filename, val); */
    6794              : 
    6795         9772 :   return true;
    6796              : }
    6797              : 
    6798              : 
    6799              : /* Given module, dump it to disk.  If there was an error while
    6800              :    processing the module, dump_flag will be set to zero and we delete
    6801              :    the module file, even if it was already there.  */
    6802              : 
    6803              : static void
    6804        10060 : dump_module (const char *name, int dump_flag)
    6805              : {
    6806        10060 :   int n;
    6807        10060 :   char *filename, *filename_tmp;
    6808        10060 :   uLong crc, crc_old;
    6809              : 
    6810        10060 :   module_name = gfc_get_string ("%s", name);
    6811              : 
    6812        10060 :   if (dump_smod)
    6813              :     {
    6814          478 :       name = submodule_name;
    6815          478 :       n = strlen (name) + strlen (SUBMODULE_EXTENSION) + 1;
    6816              :     }
    6817              :   else
    6818         9582 :     n = strlen (name) + strlen (MODULE_EXTENSION) + 1;
    6819              : 
    6820        10060 :   if (gfc_option.module_dir != NULL)
    6821              :     {
    6822            0 :       n += strlen (gfc_option.module_dir);
    6823            0 :       filename = (char *) alloca (n);
    6824            0 :       strcpy (filename, gfc_option.module_dir);
    6825            0 :       strcat (filename, name);
    6826              :     }
    6827              :   else
    6828              :     {
    6829        10060 :       filename = (char *) alloca (n);
    6830        10060 :       strcpy (filename, name);
    6831              :     }
    6832              : 
    6833        10060 :   if (dump_smod)
    6834          478 :     strcat (filename, SUBMODULE_EXTENSION);
    6835              :   else
    6836         9582 :   strcat (filename, MODULE_EXTENSION);
    6837              : 
    6838              :   /* Name of the temporary file used to write the module.  */
    6839        10060 :   filename_tmp = (char *) alloca (n + 1);
    6840        10060 :   strcpy (filename_tmp, filename);
    6841        10060 :   strcat (filename_tmp, "0");
    6842              : 
    6843              :   /* There was an error while processing the module.  We delete the
    6844              :      module file, even if it was already there.  */
    6845        10060 :   if (!dump_flag)
    6846              :     {
    6847          480 :       remove (filename);
    6848          480 :       return;
    6849              :     }
    6850              : 
    6851         9580 :   if (gfc_cpp_makedep ())
    6852            0 :     gfc_cpp_add_target (filename);
    6853              : 
    6854              :   /* Write the module to the temporary file.  */
    6855         9580 :   module_fp = gzopen (filename_tmp, "w");
    6856         9580 :   if (module_fp == NULL)
    6857            0 :     gfc_fatal_error ("Cannot open module file %qs for writing at %C: %s",
    6858            0 :                      filename_tmp, xstrerror (errno));
    6859              : 
    6860              :   /* Use lbasename to ensure module files are reproducible regardless
    6861              :      of the build path (see the reproducible builds project).  */
    6862         9580 :   gzprintf (module_fp, "GFORTRAN module version '%s' created from %s\n",
    6863              :             MOD_VERSION, lbasename (gfc_source_file));
    6864              : 
    6865              :   /* Write the module itself.  */
    6866         9580 :   iomode = IO_OUTPUT;
    6867              : 
    6868         9580 :   init_pi_tree ();
    6869              : 
    6870         9580 :   write_module ();
    6871              : 
    6872         9580 :   free_pi_tree (pi_root);
    6873         9580 :   pi_root = NULL;
    6874              : 
    6875         9580 :   write_char ('\n');
    6876              : 
    6877         9580 :   if (gzclose (module_fp))
    6878            0 :     gfc_fatal_error ("Error writing module file %qs for writing: %s",
    6879            0 :                      filename_tmp, xstrerror (errno));
    6880              : 
    6881              :   /* Read the CRC32 from the gzip trailers of the module files and
    6882              :      compare.  */
    6883         9580 :   if (!read_crc32_from_module_file (filename_tmp, &crc)
    6884         9580 :       || !read_crc32_from_module_file (filename, &crc_old)
    6885         9772 :       || crc_old != crc)
    6886              :     {
    6887              :       /* Module file have changed, replace the old one.  */
    6888         9392 :       if (remove (filename) && errno != ENOENT)
    6889            0 :         gfc_fatal_error ("Cannot delete module file %qs: %s", filename,
    6890              :                          xstrerror (errno));
    6891         9392 :       if (rename (filename_tmp, filename))
    6892            0 :         gfc_fatal_error ("Cannot rename module file %qs to %qs: %s",
    6893            0 :                          filename_tmp, filename, xstrerror (errno));
    6894              :     }
    6895              :   else
    6896              :     {
    6897          188 :       if (remove (filename_tmp))
    6898            0 :         gfc_fatal_error ("Cannot delete temporary module file %qs: %s",
    6899            0 :                          filename_tmp, xstrerror (errno));
    6900              :     }
    6901              : }
    6902              : 
    6903              : 
    6904              : /* Suppress the output of a .smod file by module, if no module
    6905              :    procedures have been seen.  */
    6906              : static bool no_module_procedures;
    6907              : 
    6908              : static void
    6909       150367 : check_for_module_procedures (gfc_symbol *sym)
    6910              : {
    6911       150367 :   if (sym && sym->attr.module_procedure)
    6912         1074 :     no_module_procedures = false;
    6913       150367 : }
    6914              : 
    6915              : 
    6916              : void
    6917         9810 : gfc_dump_module (const char *name, int dump_flag)
    6918              : {
    6919         9810 :   if (gfc_state_stack->state == COMP_SUBMODULE)
    6920          228 :     dump_smod = true;
    6921              :   else
    6922         9582 :     dump_smod =false;
    6923              : 
    6924         9810 :   no_module_procedures = true;
    6925         9810 :   gfc_traverse_ns (gfc_current_ns, check_for_module_procedures);
    6926              : 
    6927         9810 :   dump_module (name, dump_flag);
    6928              : 
    6929         9810 :   if (no_module_procedures || dump_smod)
    6930              :     return;
    6931              : 
    6932              :   /* Write a submodule file from a module.  The 'dump_smod' flag switches
    6933              :      off the check for PRIVATE entities.  */
    6934          250 :   dump_smod = true;
    6935          250 :   submodule_name = module_name;
    6936          250 :   dump_module (name, dump_flag);
    6937          250 :   dump_smod = false;
    6938              : }
    6939              : 
    6940              : static void
    6941        22935 : create_intrinsic_function (const char *name, int id,
    6942              :                            const char *modname, intmod_id module,
    6943              :                            bool subroutine, gfc_symbol *result_type)
    6944              : {
    6945        22935 :   gfc_intrinsic_sym *isym;
    6946        22935 :   gfc_symtree *tmp_symtree;
    6947        22935 :   gfc_symbol *sym;
    6948              : 
    6949        22935 :   tmp_symtree = gfc_find_symtree (gfc_current_ns->sym_root, name);
    6950        22935 :   if (tmp_symtree)
    6951              :     {
    6952           42 :       if (tmp_symtree->n.sym && tmp_symtree->n.sym->module
    6953           42 :           && strcmp (modname, tmp_symtree->n.sym->module) == 0)
    6954           42 :         return;
    6955            0 :       gfc_error ("Symbol %qs at %C already declared", name);
    6956            0 :       return;
    6957              :     }
    6958              : 
    6959        22893 :   gfc_get_sym_tree (name, gfc_current_ns, &tmp_symtree, false);
    6960        22893 :   sym = tmp_symtree->n.sym;
    6961              : 
    6962        22893 :   if (subroutine)
    6963              :     {
    6964         6342 :       gfc_isym_id isym_id = gfc_isym_id_by_intmod (module, id);
    6965         6342 :       isym = gfc_intrinsic_subroutine_by_id (isym_id);
    6966         6342 :       sym->attr.subroutine = 1;
    6967              :     }
    6968              :   else
    6969              :     {
    6970        16551 :       gfc_isym_id isym_id = gfc_isym_id_by_intmod (module, id);
    6971        16551 :       isym = gfc_intrinsic_function_by_id (isym_id);
    6972              : 
    6973        16551 :       sym->attr.function = 1;
    6974        16551 :       if (result_type)
    6975              :         {
    6976         6442 :           sym->ts.type = BT_DERIVED;
    6977         6442 :           sym->ts.u.derived = result_type;
    6978         6442 :           sym->ts.is_c_interop = 1;
    6979         6442 :           isym->ts.f90_type = BT_VOID;
    6980         6442 :           isym->ts.type = BT_DERIVED;
    6981         6442 :           isym->ts.f90_type = BT_VOID;
    6982         6442 :           isym->ts.u.derived = result_type;
    6983         6442 :           isym->ts.is_c_interop = 1;
    6984              :         }
    6985              :     }
    6986        22893 :   gcc_assert (isym);
    6987              : 
    6988        22893 :   sym->attr.flavor = FL_PROCEDURE;
    6989        22893 :   sym->attr.intrinsic = 1;
    6990              : 
    6991        22893 :   sym->module = gfc_get_string ("%s", modname);
    6992        22893 :   sym->attr.use_assoc = 1;
    6993        22893 :   sym->from_intmod = module;
    6994        22893 :   sym->intmod_sym_id = id;
    6995              : }
    6996              : 
    6997              : 
    6998              : /* Import the intrinsic ISO_C_BINDING module, generating symbols in
    6999              :    the current namespace for all named constants, pointer types, and
    7000              :    procedures in the module unless the only clause was used or a rename
    7001              :    list was provided.  */
    7002              : 
    7003              : static void
    7004         9279 : import_iso_c_binding_module (void)
    7005              : {
    7006         9279 :   gfc_symbol *mod_sym = NULL, *return_type;
    7007         9279 :   gfc_symtree *mod_symtree = NULL, *tmp_symtree;
    7008         9279 :   gfc_symtree *c_ptr = NULL, *c_funptr = NULL;
    7009         9279 :   const char *iso_c_module_name = "__iso_c_binding";
    7010         9279 :   gfc_use_rename *u;
    7011         9279 :   int i;
    7012         9279 :   bool want_c_ptr = false, want_c_funptr = false;
    7013              : 
    7014              :   /* Look only in the current namespace.  */
    7015         9279 :   mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, iso_c_module_name);
    7016              : 
    7017         9279 :   if (mod_symtree == NULL)
    7018              :     {
    7019              :       /* symtree doesn't already exist in current namespace.  */
    7020         9205 :       gfc_get_sym_tree (iso_c_module_name, gfc_current_ns, &mod_symtree,
    7021              :                         false);
    7022              : 
    7023         9205 :       if (mod_symtree != NULL)
    7024         9205 :         mod_sym = mod_symtree->n.sym;
    7025              :       else
    7026            0 :         gfc_internal_error ("import_iso_c_binding_module(): Unable to "
    7027              :                             "create symbol for %s", iso_c_module_name);
    7028              : 
    7029         9205 :       mod_sym->attr.flavor = FL_MODULE;
    7030         9205 :       mod_sym->attr.intrinsic = 1;
    7031         9205 :       mod_sym->module = gfc_get_string ("%s", iso_c_module_name);
    7032         9205 :       mod_sym->from_intmod = INTMOD_ISO_C_BINDING;
    7033              :     }
    7034              : 
    7035              :   /* Check whether C_PTR or C_FUNPTR are in the include list, if so, load it;
    7036              :      check also whether C_NULL_(FUN)PTR or C_(FUN)LOC are requested, which
    7037              :      need C_(FUN)PTR.  */
    7038        18857 :   for (u = gfc_rename_list; u; u = u->next)
    7039              :     {
    7040         9578 :       if (strcmp (c_interop_kinds_table[ISOCBINDING_NULL_PTR].name,
    7041         9578 :                   u->use_name) == 0)
    7042              :         want_c_ptr = true;
    7043         9520 :       else if (strcmp (c_interop_kinds_table[ISOCBINDING_LOC].name,
    7044              :                        u->use_name) == 0)
    7045              :         want_c_ptr = true;
    7046         9393 :       else if (strcmp (c_interop_kinds_table[ISOCBINDING_NULL_FUNPTR].name,
    7047              :                        u->use_name) == 0)
    7048              :         want_c_funptr = true;
    7049         9387 :       else if (strcmp (c_interop_kinds_table[ISOCBINDING_FUNLOC].name,
    7050              :                        u->use_name) == 0)
    7051              :         want_c_funptr = true;
    7052         9354 :       else if (strcmp (c_interop_kinds_table[ISOCBINDING_PTR].name,
    7053              :                        u->use_name) == 0)
    7054              :         {
    7055         2223 :           c_ptr = generate_isocbinding_symbol (iso_c_module_name,
    7056              :                                                (iso_c_binding_symbol)
    7057              :                                                         ISOCBINDING_PTR,
    7058         2223 :                                                u->local_name[0] ? u->local_name
    7059              :                                                                 : u->use_name,
    7060              :                                                NULL, false);
    7061              :         }
    7062         7131 :       else if (strcmp (c_interop_kinds_table[ISOCBINDING_FUNPTR].name,
    7063              :                        u->use_name) == 0)
    7064              :         {
    7065          104 :           c_funptr
    7066          104 :              = generate_isocbinding_symbol (iso_c_module_name,
    7067              :                                             (iso_c_binding_symbol)
    7068              :                                                         ISOCBINDING_FUNPTR,
    7069          104 :                                              u->local_name[0] ? u->local_name
    7070              :                                                               : u->use_name,
    7071              :                                              NULL, false);
    7072              :         }
    7073              :     }
    7074              : 
    7075         9279 :   if ((want_c_ptr || !only_flag) && !c_ptr)
    7076         3184 :     c_ptr = generate_isocbinding_symbol (iso_c_module_name,
    7077              :                                          (iso_c_binding_symbol)
    7078              :                                                         ISOCBINDING_PTR,
    7079              :                                          NULL, NULL, only_flag);
    7080         9279 :   if ((want_c_funptr || !only_flag) && !c_funptr)
    7081         3148 :     c_funptr = generate_isocbinding_symbol (iso_c_module_name,
    7082              :                                             (iso_c_binding_symbol)
    7083              :                                                         ISOCBINDING_FUNPTR,
    7084              :                                             NULL, NULL, only_flag);
    7085              : 
    7086              :   /* Generate the symbols for the named constants representing
    7087              :      the kinds for intrinsic data types.  */
    7088       695925 :   for (i = 0; i < ISOCBINDING_NUMBER; i++)
    7089              :     {
    7090       686646 :       bool found = false;
    7091      1395418 :       for (u = gfc_rename_list; u; u = u->next)
    7092       708772 :         if (strcmp (c_interop_kinds_table[i].name, u->use_name) == 0)
    7093              :           {
    7094         9576 :             bool not_in_std;
    7095         9576 :             const char *name;
    7096         9576 :             u->found = 1;
    7097         9576 :             found = true;
    7098              : 
    7099         9576 :             switch (i)
    7100              :               {
    7101              : #define NAMED_FUNCTION(a,b,c,d) \
    7102              :                 case a: \
    7103              :                   not_in_std = (gfc_option.allow_std & d) == 0; \
    7104              :                   name = b; \
    7105              :                   break;
    7106              : #define NAMED_SUBROUTINE(a,b,c,d) \
    7107              :                 case a: \
    7108              :                   not_in_std = (gfc_option.allow_std & d) == 0; \
    7109              :                   name = b; \
    7110              :                   break;
    7111              : #define NAMED_INTCST(a,b,c,d) \
    7112              :                 case a: \
    7113              :                   not_in_std = (gfc_option.allow_std & d) == 0; \
    7114              :                   name = b; \
    7115              :                   break;
    7116              : #define NAMED_UINTCST(a,b,c,d) \
    7117              :                 case a: \
    7118              :                   not_in_std = (gfc_option.allow_std & d) == 0; \
    7119              :                   name = b; \
    7120              :                   break;
    7121              : #define NAMED_REALCST(a,b,c,d)                  \
    7122              :                 case a: \
    7123              :                   not_in_std = (gfc_option.allow_std & d) == 0; \
    7124              :                   name = b; \
    7125              :                   break;
    7126              : #define NAMED_CMPXCST(a,b,c,d) \
    7127              :                 case a: \
    7128              :                   not_in_std = (gfc_option.allow_std & d) == 0; \
    7129              :                   name = b; \
    7130              :                   break;
    7131              : #include "iso-c-binding.def"
    7132              :                 default:
    7133              :                   not_in_std = false;
    7134              :                   name = "";
    7135              :               }
    7136              : 
    7137         6847 :             if (not_in_std)
    7138              :               {
    7139            6 :                 gfc_error ("The symbol %qs, referenced at %L, is not "
    7140              :                            "in the selected standard", name, &u->where);
    7141            6 :                 continue;
    7142              :               }
    7143              : 
    7144         9570 :             switch (i)
    7145              :               {
    7146              : #define NAMED_FUNCTION(a,b,c,d) \
    7147              :                 case a: \
    7148              :                   if (a == ISOCBINDING_LOC) \
    7149              :                     return_type = c_ptr->n.sym; \
    7150              :                   else if (a == ISOCBINDING_FUNLOC) \
    7151              :                     return_type = c_funptr->n.sym; \
    7152              :                   else \
    7153              :                     return_type = NULL; \
    7154              :                   create_intrinsic_function (u->local_name[0] \
    7155              :                                              ? u->local_name : u->use_name, \
    7156              :                                              a, iso_c_module_name, \
    7157              :                                              INTMOD_ISO_C_BINDING, false, \
    7158              :                                              return_type); \
    7159              :                   break;
    7160              : #define NAMED_SUBROUTINE(a,b,c,d) \
    7161              :                 case a: \
    7162              :                   create_intrinsic_function (u->local_name[0] ? u->local_name \
    7163              :                                                               : u->use_name, \
    7164              :                                              a, iso_c_module_name, \
    7165              :                                              INTMOD_ISO_C_BINDING, true, NULL); \
    7166              :                   break;
    7167              : #include "iso-c-binding.def"
    7168              : 
    7169              :                 case ISOCBINDING_PTR:
    7170              :                 case ISOCBINDING_FUNPTR:
    7171              :                   /* Already handled above.  */
    7172              :                   break;
    7173         6885 :                 default:
    7174         6885 :                   if (i == ISOCBINDING_NULL_PTR)
    7175              :                     tmp_symtree = c_ptr;
    7176         6827 :                   else if (i == ISOCBINDING_NULL_FUNPTR)
    7177              :                     tmp_symtree = c_funptr;
    7178              :                   else
    7179         6821 :                     tmp_symtree = NULL;
    7180         6885 :                   generate_isocbinding_symbol (iso_c_module_name,
    7181              :                                                (iso_c_binding_symbol) i,
    7182         6885 :                                                u->local_name[0]
    7183              :                                                ? u->local_name : u->use_name,
    7184              :                                                tmp_symtree, false);
    7185              :               }
    7186              :           }
    7187              : 
    7188       686646 :       if (!found && !only_flag)
    7189              :         {
    7190              :           /* Skip, if the symbol is not in the enabled standard.  */
    7191       232837 :           switch (i)
    7192              :             {
    7193              : #define NAMED_FUNCTION(a,b,c,d) \
    7194              :               case a: \
    7195              :                 if ((gfc_option.allow_std & d) == 0) \
    7196              :                   continue; \
    7197              :                 break;
    7198              : #define NAMED_SUBROUTINE(a,b,c,d) \
    7199              :               case a: \
    7200              :                 if ((gfc_option.allow_std & d) == 0) \
    7201              :                   continue; \
    7202              :                 break;
    7203              : #define NAMED_INTCST(a,b,c,d) \
    7204              :               case a: \
    7205              :                 if ((gfc_option.allow_std & d) == 0) \
    7206              :                   continue; \
    7207              :                 break;
    7208              : #define NAMED_UINTCST(a,b,c,d) \
    7209              :               case a: \
    7210              :                 if ((gfc_option.allow_std & d) == 0) \
    7211              :                   continue; \
    7212              :                 break;
    7213              : #define NAMED_REALCST(a,b,c,d)                  \
    7214              :               case a: \
    7215              :                 if ((gfc_option.allow_std & d) == 0) \
    7216              :                   continue; \
    7217              :                 break;
    7218              : #define NAMED_CMPXCST(a,b,c,d) \
    7219              :               case a: \
    7220              :                 if ((gfc_option.allow_std & d) == 0) \
    7221              :                   continue; \
    7222              :                 break;
    7223              : #include "iso-c-binding.def"
    7224       166420 :               default:
    7225       166420 :                 ; /* Not GFC_STD_* versioned.  */
    7226              :             }
    7227              : 
    7228       166420 :           switch (i)
    7229              :             {
    7230              : #define NAMED_FUNCTION(a,b,c,d) \
    7231              :               case a: \
    7232              :                 if (a == ISOCBINDING_LOC) \
    7233              :                   return_type = c_ptr->n.sym; \
    7234              :                 else if (a == ISOCBINDING_FUNLOC) \
    7235              :                   return_type = c_funptr->n.sym; \
    7236              :                 else \
    7237              :                   return_type = NULL; \
    7238              :                 create_intrinsic_function (b, a, iso_c_module_name, \
    7239              :                                            INTMOD_ISO_C_BINDING, false, \
    7240              :                                            return_type); \
    7241              :                 break;
    7242              : #define NAMED_SUBROUTINE(a,b,c,d) \
    7243              :               case a: \
    7244              :                 create_intrinsic_function (b, a, iso_c_module_name, \
    7245              :                                            INTMOD_ISO_C_BINDING, true, NULL); \
    7246              :                   break;
    7247              : #include "iso-c-binding.def"
    7248              : 
    7249              :               case ISOCBINDING_PTR:
    7250              :               case ISOCBINDING_FUNPTR:
    7251              :                 /* Already handled above.  */
    7252              :                 break;
    7253       138183 :               default:
    7254       138183 :                 if (i == ISOCBINDING_NULL_PTR)
    7255              :                   tmp_symtree = c_ptr;
    7256       135036 :                 else if (i == ISOCBINDING_NULL_FUNPTR)
    7257              :                   tmp_symtree = c_funptr;
    7258              :                 else
    7259       131889 :                   tmp_symtree = NULL;
    7260       138183 :                 generate_isocbinding_symbol (iso_c_module_name,
    7261              :                                              (iso_c_binding_symbol) i, NULL,
    7262              :                                              tmp_symtree, false);
    7263              :             }
    7264              :         }
    7265              :    }
    7266              : 
    7267        18857 :    for (u = gfc_rename_list; u; u = u->next)
    7268              :      {
    7269         9578 :       if (u->found)
    7270         9576 :         continue;
    7271              : 
    7272            2 :       gfc_error ("Symbol %qs referenced at %L not found in intrinsic "
    7273            2 :                  "module ISO_C_BINDING", u->use_name, &u->where);
    7274              :      }
    7275         9279 : }
    7276              : 
    7277              : 
    7278              : /* Add an integer named constant from a given module.  */
    7279              : 
    7280              : static void
    7281         9822 : create_int_parameter (const char *name, int value, const char *modname,
    7282              :                       intmod_id module, int id)
    7283              : {
    7284         9822 :   gfc_symtree *tmp_symtree;
    7285         9822 :   gfc_symbol *sym;
    7286              : 
    7287         9822 :   tmp_symtree = gfc_find_symtree (gfc_current_ns->sym_root, name);
    7288         9822 :   if (tmp_symtree != NULL)
    7289              :     {
    7290            0 :       if (strcmp (modname, tmp_symtree->n.sym->module) == 0)
    7291            0 :         return;
    7292              :       else
    7293            0 :         gfc_error ("Symbol %qs already declared", name);
    7294              :     }
    7295              : 
    7296         9822 :   gfc_get_sym_tree (name, gfc_current_ns, &tmp_symtree, false);
    7297         9822 :   sym = tmp_symtree->n.sym;
    7298              : 
    7299         9822 :   sym->module = gfc_get_string ("%s", modname);
    7300         9822 :   sym->attr.flavor = FL_PARAMETER;
    7301         9822 :   sym->ts.type = BT_INTEGER;
    7302         9822 :   sym->ts.kind = gfc_default_integer_kind;
    7303         9822 :   sym->value = gfc_get_int_expr (gfc_default_integer_kind, NULL, value);
    7304         9822 :   sym->attr.use_assoc = 1;
    7305         9822 :   sym->from_intmod = module;
    7306         9822 :   sym->intmod_sym_id = id;
    7307              : }
    7308              : 
    7309              : 
    7310              : /* Value is already contained by the array constructor, but not
    7311              :    yet the shape.  */
    7312              : 
    7313              : static void
    7314         1256 : create_int_parameter_array (const char *name, int size, gfc_expr *value,
    7315              :                             const char *modname, intmod_id module, int id)
    7316              : {
    7317         1256 :   gfc_symtree *tmp_symtree;
    7318         1256 :   gfc_symbol *sym;
    7319              : 
    7320         1256 :   tmp_symtree = gfc_find_symtree (gfc_current_ns->sym_root, name);
    7321         1256 :   if (tmp_symtree != NULL)
    7322              :     {
    7323            1 :       if (tmp_symtree->n.sym->module &&
    7324            0 :           strcmp (modname, tmp_symtree->n.sym->module) == 0)
    7325            0 :         return;
    7326              :       else
    7327            1 :         gfc_error ("Symbol %qs already declared at %L conflicts with "
    7328              :                    "symbol in %qs at %C", name,
    7329              :                    &tmp_symtree->n.sym->declared_at, modname);
    7330              :     }
    7331              : 
    7332         1256 :   gfc_get_sym_tree (name, gfc_current_ns, &tmp_symtree, false);
    7333         1256 :   sym = tmp_symtree->n.sym;
    7334              : 
    7335         1256 :   sym->module = gfc_get_string ("%s", modname);
    7336         1256 :   sym->attr.flavor = FL_PARAMETER;
    7337         1256 :   sym->ts.type = BT_INTEGER;
    7338         1256 :   sym->ts.kind = gfc_default_integer_kind;
    7339         1256 :   sym->attr.use_assoc = 1;
    7340         1256 :   sym->from_intmod = module;
    7341         1256 :   sym->intmod_sym_id = id;
    7342         1256 :   sym->attr.dimension = 1;
    7343         1256 :   sym->as = gfc_get_array_spec ();
    7344         1256 :   sym->as->rank = 1;
    7345         1256 :   sym->as->type = AS_EXPLICIT;
    7346         1256 :   sym->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
    7347         1256 :   sym->as->upper[0] = gfc_get_int_expr (gfc_default_integer_kind, NULL, size);
    7348              : 
    7349         1256 :   sym->value = value;
    7350         1256 :   sym->value->shape = gfc_get_shape (1);
    7351         1256 :   mpz_init_set_ui (sym->value->shape[0], size);
    7352              : }
    7353              : 
    7354              : 
    7355              : /* Add an derived type for a given module.  */
    7356              : 
    7357              : static void
    7358         1000 : create_derived_type (const char *name, const char *modname,
    7359              :                       intmod_id module, int id)
    7360              : {
    7361         1000 :   gfc_symtree *tmp_symtree;
    7362         1000 :   gfc_symbol *sym, *dt_sym;
    7363         1000 :   gfc_interface *intr, *head;
    7364              : 
    7365         1000 :   tmp_symtree = gfc_find_symtree (gfc_current_ns->sym_root, name);
    7366         1000 :   if (tmp_symtree != NULL)
    7367              :     {
    7368            0 :       if (strcmp (modname, tmp_symtree->n.sym->module) == 0)
    7369            0 :         return;
    7370              :       else
    7371            0 :         gfc_error ("Symbol %qs already declared", name);
    7372              :     }
    7373              : 
    7374         1000 :   gfc_get_sym_tree (name, gfc_current_ns, &tmp_symtree, false);
    7375         1000 :   sym = tmp_symtree->n.sym;
    7376         1000 :   sym->module = gfc_get_string ("%s", modname);
    7377         1000 :   sym->from_intmod = module;
    7378         1000 :   sym->intmod_sym_id = id;
    7379         1000 :   sym->attr.flavor = FL_PROCEDURE;
    7380         1000 :   sym->attr.function = 1;
    7381         1000 :   sym->attr.generic = 1;
    7382              : 
    7383         1000 :   gfc_get_sym_tree (gfc_dt_upper_string (sym->name),
    7384              :                     gfc_current_ns, &tmp_symtree, false);
    7385         1000 :   dt_sym = tmp_symtree->n.sym;
    7386         1000 :   dt_sym->name = gfc_get_string ("%s", sym->name);
    7387         1000 :   dt_sym->attr.flavor = FL_DERIVED;
    7388         1000 :   dt_sym->attr.private_comp = 1;
    7389         1000 :   dt_sym->attr.zero_comp = 1;
    7390         1000 :   dt_sym->attr.use_assoc = 1;
    7391         1000 :   dt_sym->module = gfc_get_string ("%s", modname);
    7392         1000 :   dt_sym->from_intmod = module;
    7393         1000 :   dt_sym->intmod_sym_id = id;
    7394              : 
    7395         1000 :   head = sym->generic;
    7396         1000 :   intr = gfc_get_interface ();
    7397         1000 :   intr->sym = dt_sym;
    7398         1000 :   intr->where = gfc_current_locus;
    7399         1000 :   intr->next = head;
    7400         1000 :   sym->generic = intr;
    7401         1000 :   sym->attr.if_source = IFSRC_DECL;
    7402              : }
    7403              : 
    7404              : 
    7405              : /* Read the contents of the module file into a temporary buffer.  */
    7406              : 
    7407              : static void
    7408        13283 : read_module_to_tmpbuf ()
    7409              : {
    7410              :   /* We don't know the uncompressed size, so enlarge the buffer as
    7411              :      needed.  */
    7412        13283 :   int cursz = 4096;
    7413        13283 :   int rsize = cursz;
    7414        13283 :   int len = 0;
    7415              : 
    7416        13283 :   module_content = XNEWVEC (char, cursz);
    7417              : 
    7418        54529 :   while (1)
    7419              :     {
    7420        33906 :       int nread = gzread (module_fp, module_content + len, rsize);
    7421        33906 :       len += nread;
    7422        33906 :       if (nread < rsize)
    7423              :         break;
    7424        20623 :       cursz *= 2;
    7425        20623 :       module_content = XRESIZEVEC (char, module_content, cursz);
    7426        20623 :       rsize = cursz - len;
    7427        20623 :     }
    7428              : 
    7429        13283 :   module_content = XRESIZEVEC (char, module_content, len + 1);
    7430        13283 :   module_content[len] = '\0';
    7431              : 
    7432        13283 :   module_pos = 0;
    7433        13283 : }
    7434              : 
    7435              : 
    7436              : /* USE the ISO_FORTRAN_ENV intrinsic module.  */
    7437              : 
    7438              : static void
    7439          602 : use_iso_fortran_env_module (void)
    7440              : {
    7441          602 :   static char mod[] = "iso_fortran_env";
    7442          602 :   gfc_use_rename *u;
    7443          602 :   gfc_symbol *mod_sym;
    7444          602 :   gfc_symtree *mod_symtree;
    7445          602 :   gfc_expr *expr;
    7446          602 :   int i, j;
    7447              : 
    7448          602 :   intmod_sym symbol[] = {
    7449              : #define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
    7450              : #define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
    7451              : #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
    7452              : #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
    7453              : #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
    7454              : #define NAMED_SUBROUTINE(a,b,c,d) { a, b, c, d },
    7455              : #include "iso-fortran-env.def"
    7456              :     { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
    7457              : 
    7458              :   /* We could have used c in the NAMED_{,U}INTCST macros
    7459              :      instead of 0, but then current g++ expands the initialization
    7460              :      as clearing the whole object followed by explicit stores of
    7461              :      all the non-zero elements (over 150), while by using 0s for
    7462              :      the non-constant initializers and initializing them afterwards
    7463              :      g++ will often copy everything from .rodata and then only override
    7464              :      over 30 non-constant ones.  */
    7465          602 :   i = 0;
    7466              : #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
    7467              : #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
    7468              : #define NAMED_KINDARRAY(a,b,c,d) i++;
    7469              : #define NAMED_DERIVED_TYPE(a,b,c,d) i++;
    7470              : #define NAMED_FUNCTION(a,b,c,d) i++;
    7471              : #define NAMED_SUBROUTINE(a,b,c,d) i++;
    7472              : #include "iso-fortran-env.def"
    7473          602 :   gcc_checking_assert (i == (int) ARRAY_SIZE (symbol) - 1);
    7474              : 
    7475              :   /* Generate the symbol for the module itself.  */
    7476          602 :   mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, mod);
    7477          602 :   if (mod_symtree == NULL)
    7478              :     {
    7479          601 :       gfc_get_sym_tree (mod, gfc_current_ns, &mod_symtree, false);
    7480          601 :       gcc_assert (mod_symtree);
    7481          601 :       mod_sym = mod_symtree->n.sym;
    7482              : 
    7483          601 :       mod_sym->attr.flavor = FL_MODULE;
    7484          601 :       mod_sym->attr.intrinsic = 1;
    7485          601 :       mod_sym->module = gfc_get_string ("%s", mod);
    7486          601 :       mod_sym->from_intmod = INTMOD_ISO_FORTRAN_ENV;
    7487              :     }
    7488              :   else
    7489            1 :     if (!mod_symtree->n.sym->attr.intrinsic)
    7490            1 :       gfc_error ("Use of intrinsic module %qs at %C conflicts with "
    7491              :                  "non-intrinsic module name used previously", mod);
    7492              : 
    7493              :   /* Generate the symbols for the module integer named constants.  */
    7494              : 
    7495        27090 :   for (i = 0; symbol[i].name; i++)
    7496              :     {
    7497        26488 :       bool found = false;
    7498        48664 :       for (u = gfc_rename_list; u; u = u->next)
    7499              :         {
    7500        22176 :           if (strcmp (symbol[i].name, u->use_name) == 0)
    7501              :             {
    7502          504 :               found = true;
    7503          504 :               u->found = 1;
    7504              : 
    7505          504 :               if (!gfc_notify_std (symbol[i].standard, "The symbol %qs, "
    7506              :                                    "referenced at %L, is not in the selected "
    7507              :                                    "standard", symbol[i].name, &u->where))
    7508           11 :                 continue;
    7509              : 
    7510          493 :               if ((flag_default_integer || flag_default_real_8)
    7511            2 :                   && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
    7512            0 :                 gfc_warning_now (0, "Use of the NUMERIC_STORAGE_SIZE named "
    7513              :                                  "constant from intrinsic module "
    7514              :                                  "ISO_FORTRAN_ENV at %L is incompatible with "
    7515              :                                  "option %qs", &u->where,
    7516              :                                  flag_default_integer
    7517              :                                    ? "-fdefault-integer-8"
    7518              :                                    : "-fdefault-real-8");
    7519          493 :               switch (symbol[i].id)
    7520              :                 {
    7521              : #define NAMED_INTCST(a,b,c,d) \
    7522              :                 case a:
    7523              : #include "iso-fortran-env.def"
    7524          327 :                   create_int_parameter (u->local_name[0] ? u->local_name
    7525              :                                                          : u->use_name,
    7526              :                                         symbol[i].value, mod,
    7527              :                                         INTMOD_ISO_FORTRAN_ENV, symbol[i].id);
    7528          327 :                   break;
    7529              : 
    7530              : #define NAMED_UINTCST(a,b,c,d) \
    7531              :                 case a:
    7532              : #include "iso-fortran-env.def"
    7533           30 :                   create_int_parameter (u->local_name[0] ? u->local_name
    7534              :                                                          : u->use_name,
    7535              :                                         symbol[i].value, mod,
    7536              :                                         INTMOD_ISO_FORTRAN_ENV, symbol[i].id);
    7537           30 :                   break;
    7538              : 
    7539              : #define NAMED_KINDARRAY(a,b,KINDS,d) \
    7540              :                 case a:\
    7541              :                   expr = gfc_get_array_expr (BT_INTEGER, \
    7542              :                                              gfc_default_integer_kind,\
    7543              :                                              NULL); \
    7544              :                   for (j = 0; KINDS[j].kind != 0; j++) \
    7545              :                     gfc_constructor_append_expr (&expr->value.constructor, \
    7546              :                         gfc_get_int_expr (gfc_default_integer_kind, NULL, \
    7547              :                                           KINDS[j].kind), NULL); \
    7548              :                   create_int_parameter_array (u->local_name[0] ? u->local_name \
    7549              :                                                          : u->use_name, \
    7550              :                                               j, expr, mod, \
    7551              :                                               INTMOD_ISO_FORTRAN_ENV, \
    7552              :                                               symbol[i].id); \
    7553              :                   break;
    7554              : #include "iso-fortran-env.def"
    7555              : 
    7556              : #define NAMED_DERIVED_TYPE(a,b,TYPE,STD) \
    7557              :                 case a:
    7558              : #include "iso-fortran-env.def"
    7559           85 :                   create_derived_type (u->local_name[0] ? u->local_name
    7560              :                                                         : u->use_name,
    7561              :                                        mod, INTMOD_ISO_FORTRAN_ENV,
    7562              :                                        symbol[i].id);
    7563           85 :                   break;
    7564              : 
    7565              : #define NAMED_FUNCTION(a,b,c,d) \
    7566              :                 case a:
    7567              : #include "iso-fortran-env.def"
    7568           15 :                   create_intrinsic_function (u->local_name[0] ? u->local_name
    7569              :                                                               : u->use_name,
    7570              :                                              symbol[i].id, mod,
    7571              :                                              INTMOD_ISO_FORTRAN_ENV, false,
    7572              :                                              NULL);
    7573           15 :                   break;
    7574              : 
    7575            0 :                 default:
    7576            0 :                   gcc_unreachable ();
    7577              :                 }
    7578              :             }
    7579              :         }
    7580              : 
    7581        26488 :       if (!found && !only_flag)
    7582              :         {
    7583        13537 :           if ((gfc_option.allow_std & symbol[i].standard) == 0)
    7584         1328 :             continue;
    7585              : 
    7586        12209 :           if ((flag_default_integer || flag_default_real_8)
    7587            0 :               && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
    7588            0 :             gfc_warning_now (0,
    7589              :                              "Use of the NUMERIC_STORAGE_SIZE named constant "
    7590              :                              "from intrinsic module ISO_FORTRAN_ENV at %C is "
    7591              :                              "incompatible with option %s",
    7592              :                              flag_default_integer
    7593              :                                 ? "-fdefault-integer-8" : "-fdefault-real-8");
    7594              : 
    7595        12209 :           switch (symbol[i].id)
    7596              :             {
    7597              : #define NAMED_INTCST(a,b,c,d) \
    7598              :             case a:
    7599              : #include "iso-fortran-env.def"
    7600         9461 :               create_int_parameter (symbol[i].name, symbol[i].value, mod,
    7601              :                                     INTMOD_ISO_FORTRAN_ENV, symbol[i].id);
    7602         9461 :               break;
    7603              : 
    7604              : #define NAMED_UINTCST(a,b,c,d)                  \
    7605              :             case a:
    7606              : #include "iso-fortran-env.def"
    7607            4 :               create_int_parameter (symbol[i].name, symbol[i].value, mod,
    7608              :                                     INTMOD_ISO_FORTRAN_ENV, symbol[i].id);
    7609            4 :               break;
    7610              : 
    7611              : #define NAMED_KINDARRAY(a,b,KINDS,d) \
    7612              :             case a:\
    7613              :               expr = gfc_get_array_expr (BT_INTEGER, gfc_default_integer_kind, \
    7614              :                                          NULL); \
    7615              :               for (j = 0; KINDS[j].kind != 0; j++) \
    7616              :                 gfc_constructor_append_expr (&expr->value.constructor, \
    7617              :                       gfc_get_int_expr (gfc_default_integer_kind, NULL, \
    7618              :                                         KINDS[j].kind), NULL); \
    7619              :             create_int_parameter_array (symbol[i].name, j, expr, mod, \
    7620              :                                         INTMOD_ISO_FORTRAN_ENV, symbol[i].id);\
    7621              :             break;
    7622              : #include "iso-fortran-env.def"
    7623              : 
    7624              : #define NAMED_DERIVED_TYPE(a,b,TYPE,STD) \
    7625              :           case a:
    7626              : #include "iso-fortran-env.def"
    7627          915 :             create_derived_type (symbol[i].name, mod, INTMOD_ISO_FORTRAN_ENV,
    7628              :                                  symbol[i].id);
    7629          915 :             break;
    7630              : 
    7631              : #define NAMED_FUNCTION(a,b,c,d) \
    7632              :           case a:
    7633              : #include "iso-fortran-env.def"
    7634          609 :             create_intrinsic_function (symbol[i].name, symbol[i].id, mod,
    7635              :                                        INTMOD_ISO_FORTRAN_ENV, false, NULL);
    7636          609 :             break;
    7637              : 
    7638            0 :           default:
    7639            0 :             gcc_unreachable ();
    7640              :           }
    7641              :         }
    7642              :     }
    7643              : 
    7644         1106 :   for (u = gfc_rename_list; u; u = u->next)
    7645              :     {
    7646          504 :       if (u->found)
    7647          504 :         continue;
    7648              : 
    7649            0 :       gfc_error ("Symbol %qs referenced at %L not found in intrinsic "
    7650            0 :                      "module ISO_FORTRAN_ENV", u->use_name, &u->where);
    7651              :     }
    7652          602 : }
    7653              : 
    7654              : 
    7655              : /* Process a USE directive.  */
    7656              : 
    7657              : static void
    7658        23168 : gfc_use_module (gfc_use_list *module)
    7659              : {
    7660        23168 :   char *filename;
    7661        23168 :   gfc_state_data *p;
    7662        23168 :   int c, line, start;
    7663        23168 :   gfc_symtree *mod_symtree;
    7664        23168 :   gfc_use_list *use_stmt;
    7665        23168 :   locus old_locus = gfc_current_locus;
    7666              : 
    7667        23168 :   gfc_current_locus = module->where;
    7668        23168 :   module_name = module->module_name;
    7669        23168 :   gfc_rename_list = module->rename;
    7670        23168 :   only_flag = module->only_flag;
    7671        23168 :   current_intmod = INTMOD_NONE;
    7672              : 
    7673        23168 :   if (!only_flag)
    7674        14964 :     gfc_warning_now (OPT_Wuse_without_only,
    7675              :                      "USE statement at %C has no ONLY qualifier");
    7676              : 
    7677        23168 :   if (gfc_state_stack->state == COMP_MODULE
    7678        20671 :       || module->submodule_name == NULL)
    7679              :     {
    7680        22939 :       filename = XALLOCAVEC (char, strlen (module_name)
    7681              :                                    + strlen (MODULE_EXTENSION) + 1);
    7682        22939 :       strcpy (filename, module_name);
    7683        22939 :       strcat (filename, MODULE_EXTENSION);
    7684              :     }
    7685              :   else
    7686              :     {
    7687          229 :       filename = XALLOCAVEC (char, strlen (module->submodule_name)
    7688              :                                    + strlen (SUBMODULE_EXTENSION) + 1);
    7689          229 :       strcpy (filename, module->submodule_name);
    7690          229 :       strcat (filename, SUBMODULE_EXTENSION);
    7691              :     }
    7692              : 
    7693              :   /* First, try to find an non-intrinsic module, unless the USE statement
    7694              :      specified that the module is intrinsic.  */
    7695        23168 :   module_fp = NULL;
    7696        23168 :   if (!module->intrinsic)
    7697        19791 :     module_fp = gzopen_included_file (filename, true, true);
    7698              : 
    7699              :   /* Then, see if it's an intrinsic one, unless the USE statement
    7700              :      specified that the module is non-intrinsic.  */
    7701        23168 :   if (module_fp == NULL && !module->non_intrinsic)
    7702              :     {
    7703        11097 :       if (strcmp (module_name, "iso_fortran_env") == 0
    7704        11097 :           && gfc_notify_std (GFC_STD_F2003, "ISO_FORTRAN_ENV "
    7705              :                              "intrinsic module at %C"))
    7706              :        {
    7707          602 :          use_iso_fortran_env_module ();
    7708          602 :          free_rename (module->rename);
    7709          602 :          module->rename = NULL;
    7710          602 :          gfc_current_locus = old_locus;
    7711          602 :          module->intrinsic = true;
    7712         9881 :          return;
    7713              :        }
    7714              : 
    7715        10495 :       if (strcmp (module_name, "iso_c_binding") == 0
    7716        10495 :           && gfc_notify_std (GFC_STD_F2003, "ISO_C_BINDING module at %C"))
    7717              :         {
    7718         9279 :           import_iso_c_binding_module();
    7719         9279 :           free_rename (module->rename);
    7720         9279 :           module->rename = NULL;
    7721         9279 :           gfc_current_locus = old_locus;
    7722         9279 :           module->intrinsic = true;
    7723         9279 :           return;
    7724              :         }
    7725              : 
    7726         1216 :       module_fp = gzopen_intrinsic_module (filename);
    7727              : 
    7728         1216 :       if (module_fp == NULL && module->intrinsic)
    7729            0 :         gfc_fatal_error ("Cannot find an intrinsic module named %qs at %C",
    7730              :                          module_name);
    7731              : 
    7732              :       /* Check for the IEEE modules, so we can mark their symbols
    7733              :          accordingly when we read them.  */
    7734         1216 :       if (strcmp (module_name, "ieee_features") == 0
    7735         1216 :           && gfc_notify_std (GFC_STD_F2003, "IEEE_FEATURES module at %C"))
    7736              :         {
    7737           56 :           current_intmod = INTMOD_IEEE_FEATURES;
    7738              :         }
    7739         1160 :       else if (strcmp (module_name, "ieee_exceptions") == 0
    7740         1160 :                && gfc_notify_std (GFC_STD_F2003,
    7741              :                                   "IEEE_EXCEPTIONS module at %C"))
    7742              :         {
    7743           60 :           current_intmod = INTMOD_IEEE_EXCEPTIONS;
    7744              :         }
    7745         1100 :       else if (strcmp (module_name, "ieee_arithmetic") == 0
    7746         1100 :                && gfc_notify_std (GFC_STD_F2003,
    7747              :                                   "IEEE_ARITHMETIC module at %C"))
    7748              :         {
    7749          405 :           current_intmod = INTMOD_IEEE_ARITHMETIC;
    7750              :         }
    7751              :     }
    7752              : 
    7753        13287 :   if (module_fp == NULL)
    7754              :     {
    7755            4 :       if (gfc_state_stack->state != COMP_SUBMODULE
    7756            3 :           && module->submodule_name == NULL)
    7757            3 :         gfc_fatal_error ("Cannot open module file %qs for reading at %C: %s",
    7758            3 :                          filename, xstrerror (errno));
    7759              :       else
    7760            1 :         gfc_fatal_error ("Module file %qs has not been generated, either "
    7761              :                          "because the module does not contain a MODULE "
    7762              :                          "PROCEDURE or there is an error in the module.",
    7763              :                          filename);
    7764              :     }
    7765              : 
    7766              :   /* Check that we haven't already USEd an intrinsic module with the
    7767              :      same name.  */
    7768              : 
    7769        13283 :   mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, module_name);
    7770        13283 :   if (mod_symtree && mod_symtree->n.sym->attr.intrinsic)
    7771            1 :     gfc_error ("Use of non-intrinsic module %qs at %C conflicts with "
    7772              :                "intrinsic module name used previously", module_name);
    7773              : 
    7774        13283 :   iomode = IO_INPUT;
    7775        13283 :   module_line = 1;
    7776        13283 :   module_column = 1;
    7777        13283 :   start = 0;
    7778              : 
    7779        13283 :   read_module_to_tmpbuf ();
    7780        13283 :   gzclose (module_fp);
    7781              : 
    7782              :   /* Skip the first line of the module, after checking that this is
    7783              :      a gfortran module file.  */
    7784        13283 :   line = 0;
    7785       490358 :   while (line < 1)
    7786              :     {
    7787       463792 :       c = module_char ();
    7788       463792 :       if (c == EOF)
    7789            0 :         bad_module ("Unexpected end of module");
    7790       463792 :       if (start++ < 3)
    7791        39849 :         parse_name (c);
    7792       463792 :       if ((start == 1 && strcmp (atom_name, "GFORTRAN") != 0)
    7793       463792 :           || (start == 2 && strcmp (atom_name, " module") != 0))
    7794            0 :         gfc_fatal_error ("File %qs opened at %C is not a GNU Fortran"
    7795              :                          " module file", module_fullpath);
    7796       463792 :       if (start == 3)
    7797              :         {
    7798        13283 :           bool fatal = false;
    7799        13283 :           if (strcmp (atom_name, " version") != 0
    7800        13283 :               || module_char () != ' '
    7801        26566 :               || parse_atom () != ATOM_STRING)
    7802              :             fatal = true;
    7803        13283 :           else if (strcmp (atom_string, MOD_VERSION))
    7804              :             {
    7805              :               static const char *compat_mod_versions[] = COMPAT_MOD_VERSIONS;
    7806            0 :               fatal = true;
    7807            0 :               for (unsigned i = 0; i < ARRAY_SIZE (compat_mod_versions); ++i)
    7808            0 :                 if (!strcmp (atom_string, compat_mod_versions[i]))
    7809              :                   {
    7810              :                     fatal = false;
    7811              :                     break;
    7812              :                   }
    7813              :             }
    7814            0 :           if (fatal)
    7815            0 :             gfc_fatal_error ("Cannot read module file %qs opened at %C,"
    7816              :                              " because it was created by a different"
    7817              :                              " version of GNU Fortran", module_fullpath);
    7818              : 
    7819        13283 :           free (atom_string);
    7820              :         }
    7821              : 
    7822       463792 :       if (c == '\n')
    7823        13283 :         line++;
    7824              :     }
    7825              : 
    7826              :   /* Make sure we're not reading the same module that we may be building.  */
    7827        44812 :   for (p = gfc_state_stack; p; p = p->previous)
    7828        31529 :     if ((p->state == COMP_MODULE || p->state == COMP_SUBMODULE)
    7829         2254 :          && strcmp (p->sym->name, module_name) == 0)
    7830              :       {
    7831            0 :         if (p->state == COMP_SUBMODULE)
    7832            0 :           gfc_fatal_error ("Cannot USE a submodule that is currently built");
    7833              :         else
    7834            0 :           gfc_fatal_error ("Cannot USE a module that is currently built");
    7835              :       }
    7836              : 
    7837        13283 :   init_pi_tree ();
    7838        13283 :   init_true_name_tree ();
    7839              : 
    7840        13283 :   read_module ();
    7841              : 
    7842        13283 :   free_true_name (true_name_root);
    7843        13283 :   true_name_root = NULL;
    7844              : 
    7845        13283 :   free_pi_tree (pi_root);
    7846        13283 :   pi_root = NULL;
    7847              : 
    7848        13283 :   XDELETEVEC (module_content);
    7849        13283 :   module_content = NULL;
    7850              : 
    7851        13283 :   use_stmt = gfc_get_use_list ();
    7852        13283 :   *use_stmt = *module;
    7853        13283 :   use_stmt->next = gfc_current_ns->use_stmts;
    7854        13283 :   gfc_current_ns->use_stmts = use_stmt;
    7855              : 
    7856        13283 :   gfc_current_locus = old_locus;
    7857              : }
    7858              : 
    7859              : 
    7860              : /* Remove duplicated intrinsic operators from the rename list.  */
    7861              : 
    7862              : static void
    7863        23168 : rename_list_remove_duplicate (gfc_use_rename *list)
    7864              : {
    7865        23168 :   gfc_use_rename *seek, *last;
    7866              : 
    7867        36161 :   for (; list; list = list->next)
    7868        12993 :     if (list->op != INTRINSIC_USER && list->op != INTRINSIC_NONE)
    7869              :       {
    7870          113 :         last = list;
    7871          459 :         for (seek = list->next; seek; seek = last->next)
    7872              :           {
    7873          346 :             if (list->op == seek->op)
    7874              :               {
    7875            2 :                 last->next = seek->next;
    7876            2 :                 free (seek);
    7877              :               }
    7878              :             else
    7879              :               last = seek;
    7880              :           }
    7881              :       }
    7882        23168 : }
    7883              : 
    7884              : 
    7885              : /* Process all USE directives.  */
    7886              : 
    7887              : void
    7888        20047 : gfc_use_modules (void)
    7889              : {
    7890        20047 :   gfc_use_list *next, *seek, *last;
    7891              : 
    7892        43215 :   for (next = module_list; next; next = next->next)
    7893              :     {
    7894        23168 :       bool non_intrinsic = next->non_intrinsic;
    7895        23168 :       bool intrinsic = next->intrinsic;
    7896        23168 :       bool neither = !non_intrinsic && !intrinsic;
    7897              : 
    7898        27082 :       for (seek = next->next; seek; seek = seek->next)
    7899              :         {
    7900         3914 :           if (next->module_name != seek->module_name)
    7901         3740 :             continue;
    7902              : 
    7903          174 :           if (seek->non_intrinsic)
    7904              :             non_intrinsic = true;
    7905          173 :           else if (seek->intrinsic)
    7906              :             intrinsic = true;
    7907              :           else
    7908          133 :             neither = true;
    7909              :         }
    7910              : 
    7911        23168 :       if (intrinsic && neither && !non_intrinsic)
    7912              :         {
    7913            1 :           char *filename;
    7914            1 :           FILE *fp;
    7915              : 
    7916            1 :           filename = XALLOCAVEC (char,
    7917              :                                  strlen (next->module_name)
    7918              :                                  + strlen (MODULE_EXTENSION) + 1);
    7919            1 :           strcpy (filename, next->module_name);
    7920            1 :           strcat (filename, MODULE_EXTENSION);
    7921            1 :           fp = gfc_open_included_file (filename, true, true);
    7922            1 :           if (fp != NULL)
    7923              :             {
    7924            0 :               non_intrinsic = true;
    7925            0 :               fclose (fp);
    7926              :             }
    7927              :         }
    7928              : 
    7929        23168 :       last = next;
    7930        27082 :       for (seek = next->next; seek; seek = last->next)
    7931              :         {
    7932         3914 :           if (next->module_name != seek->module_name)
    7933              :             {
    7934         3740 :               last = seek;
    7935         3740 :               continue;
    7936              :             }
    7937              : 
    7938          174 :           if ((!next->intrinsic && !seek->intrinsic)
    7939           41 :               || (next->intrinsic && seek->intrinsic)
    7940            3 :               || !non_intrinsic)
    7941              :             {
    7942          172 :               if (!seek->only_flag)
    7943           18 :                 next->only_flag = false;
    7944          172 :               if (seek->rename)
    7945              :                 {
    7946              :                   gfc_use_rename *r = seek->rename;
    7947          309 :                   while (r->next)
    7948              :                     r = r->next;
    7949          167 :                   r->next = next->rename;
    7950          167 :                   next->rename = seek->rename;
    7951              :                 }
    7952          172 :               last->next = seek->next;
    7953          172 :               free (seek);
    7954          172 :             }
    7955              :           else
    7956              :             last = seek;
    7957              :         }
    7958              :     }
    7959              : 
    7960        43211 :   for (; module_list; module_list = next)
    7961              :     {
    7962        23168 :       next = module_list->next;
    7963        23168 :       rename_list_remove_duplicate (module_list->rename);
    7964        23168 :       gfc_use_module (module_list);
    7965        23164 :       free (module_list);
    7966              :     }
    7967        20043 :   module_list = NULL;
    7968        20043 :   old_module_list_tail = &module_list;
    7969        20043 :   gfc_rename_list = NULL;
    7970        20043 : }
    7971              : 
    7972              : 
    7973              : void
    7974      9432145 : gfc_free_use_stmts (gfc_use_list *use_stmts)
    7975              : {
    7976      9432145 :   gfc_use_list *next;
    7977      9445432 :   for (; use_stmts; use_stmts = next)
    7978              :     {
    7979              :       gfc_use_rename *next_rename;
    7980              : 
    7981        16198 :       for (; use_stmts->rename; use_stmts->rename = next_rename)
    7982              :         {
    7983         2911 :           next_rename = use_stmts->rename->next;
    7984         2911 :           free (use_stmts->rename);
    7985              :         }
    7986        13287 :       next = use_stmts->next;
    7987        13287 :       free (use_stmts);
    7988              :     }
    7989      9432145 : }
    7990              : 
    7991              : 
    7992              : /* Remember the end of the MODULE_LIST list, so that the list can be restored
    7993              :    to its previous state if the current statement is erroneous.  */
    7994              : 
    7995              : void
    7996      1430619 : gfc_save_module_list ()
    7997              : {
    7998      1430619 :   gfc_use_list **tail = &module_list;
    7999      1459823 :   while (*tail != NULL)
    8000        29204 :     tail = &(*tail)->next;
    8001      1430619 :   old_module_list_tail = tail;
    8002      1430619 : }
    8003              : 
    8004              : 
    8005              : /* Restore the MODULE_LIST list to its previous value and free the use
    8006              :    statements that are no longer part of the list.  */
    8007              : 
    8008              : void
    8009      8916381 : gfc_restore_old_module_list ()
    8010              : {
    8011      8916381 :   gfc_free_use_stmts (*old_module_list_tail);
    8012      8916381 :   *old_module_list_tail = NULL;
    8013      8916381 : }
    8014              : 
    8015              : 
    8016              : void
    8017        80034 : gfc_module_init_2 (void)
    8018              : {
    8019        80034 :   last_atom = ATOM_LPAREN;
    8020        80034 :   gfc_rename_list = NULL;
    8021        80034 :   module_list = NULL;
    8022        80034 : }
    8023              : 
    8024              : 
    8025              : void
    8026        80368 : gfc_module_done_2 (void)
    8027              : {
    8028        80368 :   free_rename (gfc_rename_list);
    8029        80368 :   gfc_rename_list = NULL;
    8030        80368 : }
        

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.