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

Generated by: LCOV version 2.5.0-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.