1 /*
2  * Copyright (c) 1995-2019, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 /** \file
19     \brief Fortran module support.
20  */
21 
22 #include "gbldefs.h"
23 #include "global.h"
24 #include "error.h"
25 #include "symtab.h"
26 #include "dtypeutl.h"
27 #include "semant.h"
28 #include "symutl.h"
29 #include "dinit.h"
30 #include "interf.h"
31 #include "ast.h"
32 #include "rte.h"
33 #include "soc.h"
34 #include "state.h"
35 #include "lz.h"
36 #include "dbg_out.h"
37 
38 #define MOD_SUFFIX ".mod"
39 
40 /* ModuleId is an index into usedb.base[] */
41 typedef enum {
42   NO_MODULE = 0,
43   FIRST_MODULE = 3,         /* 1 and 2 are not used */
44   ISO_C_MOD = FIRST_MODULE, /* iso_c_binding module */
45   IEEE_ARITH_MOD,           /* ieee_arithmetic module */
46   IEEE_FEATURES_MOD,        /* ieee_features module */
47   ISO_FORTRAN_ENV,          /* iso_fortan_env module */
48   NML_MOD,                  /* namelist */
49   FIRST_USER_MODULE,        /* beginning of use modules */
50   MODULE_ID_MAX = 0x7fffffff,
51 } MODULE_ID;
52 
53 /* The index into usedb of the module of the current USE statement.
54  * Set in open_module(); used in add_use_stmt() and add_use_rename();
55  * and cleared in apply_use_stmts().
56  */
57 static MODULE_ID module_id = NO_MODULE;
58 
59 static LOGICAL seen_contains;
60 
61 /* collect 'only', 'only' with rename, or just rename */
62 typedef struct _rename {
63   int local;  /* sptr representing local name; 0 if rename doesn't
64                * occur
65                */
66   int global; /* sptr representing global name */
67   int lineno;
68   char complete;    /* set when found as an intrinsic (currently
69                        iso_c only) */
70   char is_operator; /* only/rename of the global is for an operator */
71   struct _rename *next;
72 } RENAME;
73 
74 typedef struct {
75   SPTR module;          /* the name of the module in the USE statement */
76   LOGICAL unrestricted; /* entire module file is read */
77   LOGICAL submodule;    /* use of module by submodule */
78   RENAME *rename;
79   char *fullname; /* full path name of the module file */
80 } USED;
81 
82 struct {
83   SPTR *iso_c;
84   SPTR *iso_fortran;
85 } pd_mod_entries;
86 
87 /* for recording modules used in a scoping unit */
88 static struct {
89   USED *base;
90   MODULE_ID avl; /* next available use module id */
91   int sz;
92   int *ipasave_modname;
93   int ipasave_avl, ipasave_sz;
94 } usedb = {NULL, 0, 0, NULL, 0, 0};
95 
96 static int limitsptr;
97 
98 static SPTR get_iso_c_entry(const char *name);
99 static SPTR get_iso_fortran_entry(const char *name);
100 static void add_predefined_isoc_module(void);
101 static void add_predefined_iso_fortran_env_module(void);
102 static void add_predefined_ieeearith_module(void);
103 static void apply_use(MODULE_ID);
104 static int basedtype(int sym);
105 static void fix_module_common(void);
106 static void export_public_used_modules(int scopelevel);
107 static void add_to_common(int cmidx, int mem, int atstart);
108 static void export_all(void);
109 static void make_rte_descriptor(int obj, char *suffix);
110 static SPTR get_submod_sym(SPTR ancestor_module, SPTR submodule);
111 static void dbg_dump(const char *, int);
112 /* ------------------------------------------------------------------ */
113 /*   USE statement  */
114 
115 ref_symbol dbgref_symbol = {NULL, 0, NULL};
116 
117 /* Allocate memory for reference symbols with size of stb.stg_avail */
118 void
allocate_refsymbol(int symavl)119 allocate_refsymbol(int symavl)
120 {
121   if (dbgref_symbol.symnum == NULL) {
122     dbgref_symbol.symnum = (int *)(malloc((symavl + 10) * sizeof(int)));
123     dbgref_symbol.altname =
124         (mod_altptr *)(malloc((symavl + 10) * sizeof(mod_altptr)));
125     dbgref_symbol.size = symavl + 10;
126     BZERO((void *)dbgref_symbol.symnum, int, (dbgref_symbol.size));
127     BZERO((void *)dbgref_symbol.altname, mod_altptr, (dbgref_symbol.size));
128   } else if (dbgref_symbol.size <= symavl) {
129     dbgref_symbol.symnum =
130         (int *)(realloc(dbgref_symbol.symnum, (symavl + 10) * sizeof(int)));
131     dbgref_symbol.altname = (mod_altptr *)(realloc(
132         dbgref_symbol.altname, (symavl + 10) * sizeof(mod_altptr)));
133 
134     BZERO((void *)(dbgref_symbol.symnum + dbgref_symbol.size), int,
135           symavl - dbgref_symbol.size + 10);
136     BZERO((void *)(dbgref_symbol.altname + dbgref_symbol.size), mod_altptr,
137           symavl - dbgref_symbol.size + 10);
138     dbgref_symbol.size = symavl + 10;
139   }
140 }
141 
142 /* reinitialize reference symbols from symavl on,
143  * we want to keep anything under symavl because that could come from module.
144  */
145 static void
reinit_refsymbol(int symavl)146 reinit_refsymbol(int symavl)
147 {
148   int i;
149   mod_altptr symptr;
150 
151   if (symavl > dbgref_symbol.size)
152     return;
153 
154   /* zero out all symbols that are referenced in previous routine if any */
155   BZERO((void *)dbgref_symbol.symnum, int, dbgref_symbol.size);
156 
157   /* Keep USEd names around for module */
158   for (i = symavl; i < dbgref_symbol.size; ++i) {
159     for (; dbgref_symbol.altname[i]; dbgref_symbol.altname[i] = symptr) {
160       symptr = dbgref_symbol.altname[i]->next;
161       FREE(dbgref_symbol.altname[i]);
162     }
163     dbgref_symbol.altname[i] = NULL;
164   }
165 }
166 
167 /* Create link list of renames */
168 void
set_modusename(int local,int global)169 set_modusename(int local, int global)
170 {
171   if (dbgref_symbol.size <= stb.stg_avail) {
172     allocate_refsymbol(stb.stg_avail);
173   }
174 
175   /* To avoid duplicate names, because of _parser
176    * symnum should be set -2
177    */
178   if (dbgref_symbol.symnum[local] == -2) {
179     dbgref_symbol.symnum[local] = 0;
180     return;
181   }
182 
183   if (dbgref_symbol.altname[local]) {
184     if (dbgref_symbol.altname[global] == NULL) {
185       dbgref_symbol.altname[global] = dbgref_symbol.altname[local];
186     } else {
187       mod_altptr symptr = dbgref_symbol.altname[global];
188       while (symptr->next) {
189         symptr = symptr->next;
190       }
191       symptr->next = dbgref_symbol.altname[local];
192     }
193     dbgref_symbol.symnum[local] = -2;
194     dbgref_symbol.altname[local] = NULL;
195   } else {
196     const char *localname = SYMNAME(local);
197     mod_altptr symptr = dbgref_symbol.altname[global];
198     if (!symptr) {
199       /* Don't do anything if name is not changed */
200       if (strcmp(SYMNAME(global), localname) == 0) {
201         dbgref_symbol.symnum[local] = -2;
202         return;
203       }
204     }
205     /* Check if localname is already in altname list */
206     while (symptr) {
207       if (strcmp(SYMNAME(symptr->sptr), localname) == 0)
208         break;
209       symptr = symptr->next;
210     }
211     if (!symptr) {
212       symptr = (mod_altptr)malloc(sizeof(module_altname));
213       symptr->sptr = local;
214       symptr->next = dbgref_symbol.altname[global];
215       dbgref_symbol.altname[global] = symptr;
216     }
217     dbgref_symbol.symnum[local] = -2;
218   }
219 }
220 
221 void
use_init(void)222 use_init(void)
223 {
224   usedb.ipasave_avl = 0;
225   reinit_refsymbol(stb.stg_avail);
226 }
227 
228 /* initialize for a sequence of USE statements */
229 void
init_use_stmts(void)230 init_use_stmts(void)
231 {
232   if (usedb.base == NULL) {
233     usedb.sz = 32;
234     NEW(usedb.base, USED, usedb.sz);
235     usedb.avl = FIRST_USER_MODULE;
236     BZERO(usedb.base, USED, FIRST_USER_MODULE);
237   }
238 }
239 
240 /** \brief Process a "USE module" statement. The module is specified
241  *         in module_id.
242  */
243 void
add_use_stmt()244 add_use_stmt()
245 {
246   assert(module_id != NO_MODULE, "module_id must be set", 0, ERR_Fatal);
247   usedb.base[module_id].unrestricted = TRUE;
248 }
249 
250 /* Use module from submodule */
251 void
add_submodule_use(void)252 add_submodule_use(void)
253 {
254   assert(module_id != NO_MODULE, "module_id must be set", 0, ERR_Fatal);
255   usedb.base[module_id].unrestricted = TRUE;
256   usedb.base[module_id].submodule = TRUE;
257 }
258 
259 #define VALID_RENAME_SYM(sptr)                            \
260   (sptr > stb.firstusym &&                                \
261    (ST_ISVAR(STYPEG(sptr)) || STYPEG(sptr) == ST_ALIAS || \
262     STYPEG(sptr) == ST_PROC || STYPEG(sptr) == ST_MODPROC))
263 
264 /** \brief Process a USE ONLY statement, optionally renaming 'global'
265  *         as 'local'. The module is specified in 'module_id'.
266  * \return The updated \a global symbol.
267  *
268  * The USE statement can be any of these forms:
269  *   USE module, ONLY: global
270  *   USE module, ONLY: local => global
271  *   USE module, ONLY: OPERATOR(.xx.)
272  *   USE module, ONLY: ASSIGNMENT(=)
273  * is_operator is set for the last two.
274  */
275 SPTR
add_use_rename(SPTR local,SPTR global,LOGICAL is_operator)276 add_use_rename(SPTR local, SPTR global, LOGICAL is_operator)
277 {
278   RENAME *pr;
279   int original_global = global;
280 
281   assert(module_id != NO_MODULE, "module_id must be set", 0, ERR_Fatal);
282   assert(global > NOSYM, "global must be set", global, ERR_Fatal);
283   pr = (RENAME *)getitem(USE_AREA, sizeof(RENAME));
284   pr->complete = 0;
285   pr->is_operator = is_operator;
286   pr->next = usedb.base[module_id].rename;
287   usedb.base[module_id].rename = pr;
288   /*
289    * NOTE: MAY want to skip the ensuing 'if' when the rename is
290    * for an OPERATOR (is_operator is set) since an ST_OPERATOR is in
291    * its own overloading class!
292    */
293   if (!VALID_RENAME_SYM(global)) {
294     SPTR sptr;
295     for (sptr = first_hash(global); sptr; sptr = HASHLKG(sptr)) {
296       if (NMPTRG(sptr) == NMPTRG(global) && SCOPEG(sptr) == SCOPEG(global) &&
297           VALID_RENAME_SYM(sptr)) {
298         if (ST_ISVAR(sptr) && SYMLKG(sptr) &&
299             STYPEG(SYMLKG(sptr)) == ST_ALIAS &&
300             SCOPEG(SYMLKG(sptr)) == usedb.base[module_id].module) {
301           global = SYMLKG(sptr);
302         } else {
303           global = sptr;
304         }
305       }
306     }
307   }
308 
309   if (local && STYPEG(local) == ST_ALIAS && PRIVATEG(local) &&
310       SCOPEG(local) != curr_scope()->sptr) {
311     /* local is a private rename from another module
312      * build and use a rename symbol in this scope.
313      */
314     int newlocal = insert_sym(local);
315     DTYPEP(newlocal, DTYPEG(global));
316     SCOPEP(newlocal, curr_scope()->sptr);
317     pr->local = newlocal;
318     HIDDENP(SYMLKG(local), 0);
319     pr->global = SYMLKG(local);
320     pr->lineno = gbl.lineno;
321     return pr->global;
322   }
323   if (STYPEG(global) == ST_ALIAS && PRIVATEG(global) &&
324       SCOPEG(global) != curr_scope()->sptr) {
325     /* global is an alias from another scope, generate an alias for the
326      * current scope */
327     SPTR newglobal = insert_sym(global);
328     pr->global = newglobal;
329     pr->local = local;
330     SCOPEP(newglobal, curr_scope()->sptr);
331     ENCLFUNCP(newglobal, SCOPEG(newglobal));
332     DTYPEP(newglobal, DTYPEG(global));
333     SYMLKP(newglobal, SYMLKG(global));
334     HIDDENP(SYMLKG(newglobal), 0);
335     pr->lineno = gbl.lineno;
336     return pr->global;
337   }
338 
339   if (!local && global != original_global && seen_contains &&
340       STYPEG(original_global) == ST_UNKNOWN) {
341     pr->local = original_global;
342   } else {
343     pr->local = local;
344   }
345   pr->global = global;
346   pr->lineno = gbl.lineno;
347 
348   /* Add rename 'use module, abc=>b' */
349   if (flg.debug && local && strcmp(SYMNAME(local), SYMNAME(global)) != 0)
350     set_modusename(local, global);
351 
352   return global;
353 }
354 
355 /* Look for other generic or operator symbols that should be added to
356  * the 'only' list.
357  */
358 static int
add_only(int listitem,int save_sem_scope_level)359 add_only(int listitem, int save_sem_scope_level)
360 {
361   SCOPESTACK *scope;
362   int sptr = SYMI_SPTR(listitem);
363   int stype = STYPEG(sptr);
364   int newglobal, nextnew;
365   for (newglobal = HASHLKG(sptr); newglobal; newglobal = nextnew) {
366     nextnew = HASHLKG(newglobal);
367     if (HIDDENG(newglobal))
368       continue;
369     if (NMPTRG(newglobal) != NMPTRG(sptr))
370       continue;
371     switch (STYPEG(newglobal)) {
372     case ST_ISOC:
373     case ST_CRAY:
374       /* predefined symbol, but not active in this routine */
375       continue;
376     case ST_MEMBER:
377       /* can't rename a member name */
378       continue;
379     default:;
380     }
381     scope = next_scope_sptr(curr_scope(), SCOPEG(newglobal));
382     /* found this in anything just USEd? */
383     if (get_scope_level(scope) >= save_sem_scope_level) {
384       /* check on 'except' list and private module variable */
385       if (!is_except_in_scope(scope, newglobal) && !PRIVATEG(newglobal)) {
386         /* look for generic with same name */
387         int ng = newglobal;
388         while ((STYPEG(ng) == ST_ALIAS || STYPEG(ng) == ST_MODPROC) &&
389                SYMLKG(ng) && NMPTRG(SYMLKG(ng)) == NMPTRG(newglobal)) {
390           ng = SYMLKG(ng);
391         }
392         if (STYPEG(ng) == ST_PROC && GSAMEG(ng) &&
393             SCOPEG(GSAMEG(ng)) == SCOPEG(newglobal)) {
394           /* generic with same name as specific, use the generic */
395           newglobal = GSAMEG(ng);
396         }
397         if (STYPEG(newglobal) == ST_MODPROC && SYMLKG(newglobal)) {
398           newglobal = SYMLKG(newglobal);
399         }
400         if (STYPEG(newglobal) == stype) {
401           listitem = add_symitem(newglobal, listitem);
402         }
403       }
404     }
405   }
406   return listitem;
407 }
408 
409 /* We're at the beginning of the statement after a sequence of USE statements.
410  * Apply the use statements seen.
411  * Clean up after processing the sequence of USE statements.
412  */
413 void
apply_use_stmts(void)414 apply_use_stmts(void)
415 {
416   int save_lineno;
417   MODULE_ID m_id;
418   SPTR ancestor_mod;
419 
420   ancestor_mod = NOSYM;
421   module_id = NO_MODULE;
422   if (ANCESTORG(gbl.currmod))
423     ancestor_mod = ANCESTORG(gbl.currmod);
424 
425   /*
426    * A user error could have occurred which created a situation where
427    * sem.pgphase is still PHASE_USE (USE statements have appeared) and the
428    * use table is empty.
429    */
430   if (usedb.base == NULL) {
431     usedb.ipasave_avl = 0;
432     return;
433   }
434   save_lineno = gbl.lineno;
435 
436   if (!gbl.currmod && gbl.internal <= 1) {
437     init_use_tree();
438   }
439   if (usedb.base[ISO_C_MOD].module) {
440     if (usedb.base[ISO_C_MOD].module == ancestor_mod)
441       error(1211, ERR_Severe, gbl.lineno, SYMNAME(ancestor_mod), CNULL);
442     /* use iso_c_binding */
443     add_predefined_isoc_module();
444     if (sem.interface == 0 && IN_MODULE)
445       exportb.iso_c_library = TRUE;
446     apply_use(ISO_C_MOD);
447   }
448   if (usedb.base[IEEE_ARITH_MOD].module) {
449     if (usedb.base[IEEE_ARITH_MOD].module == ancestor_mod)
450       error(1211, ERR_Severe, gbl.lineno, SYMNAME(ancestor_mod), CNULL);
451     /* use ieee_arithmetic */
452     add_predefined_ieeearith_module();
453     if (sem.interface == 0 && IN_MODULE)
454       exportb.ieee_arith_library = TRUE;
455     apply_use(IEEE_ARITH_MOD);
456   }
457   if (usedb.base[IEEE_FEATURES_MOD].module) {
458     if (usedb.base[IEEE_FEATURES_MOD].module == ancestor_mod)
459       error(1211, ERR_Severe, gbl.lineno, SYMNAME(ancestor_mod), CNULL);
460     /* use ieee_features */
461     sem.ieee_features = TRUE;
462     apply_use(IEEE_FEATURES_MOD);
463   }
464   if (usedb.base[ISO_FORTRAN_ENV].module) {
465     if (usedb.base[ISO_FORTRAN_ENV].module == ancestor_mod)
466       error(1211, ERR_Severe, gbl.lineno, SYMNAME(ancestor_mod), CNULL);
467     /* use iso_fortran_env */
468     add_predefined_iso_fortran_env_module();
469     if (sem.interface == 0 && IN_MODULE)
470       exportb.iso_fortran_env_library = TRUE;
471     apply_use(ISO_FORTRAN_ENV);
472   }
473 
474   for (m_id = FIRST_USER_MODULE; m_id < usedb.avl; m_id++) {
475     apply_use(m_id);
476   }
477 
478   gbl.lineno = save_lineno;
479   if (usedb.base) {
480     if (XBIT(89, 2) && usedb.avl > FIRST_USER_MODULE) {
481       usedb.ipasave_avl = 0;
482       if (usedb.ipasave_modname == NULL) {
483         usedb.ipasave_sz = usedb.sz;
484         NEW(usedb.ipasave_modname, int, usedb.ipasave_sz);
485       } else {
486         NEED(usedb.ipasave_avl + usedb.avl, usedb.ipasave_modname, int,
487              usedb.ipasave_sz, usedb.ipasave_sz + usedb.avl + 10);
488       }
489       for (m_id = FIRST_USER_MODULE; m_id < usedb.avl; ++m_id) {
490         if (usedb.base[m_id].module) {
491           usedb.ipasave_modname[usedb.ipasave_avl++] = usedb.base[m_id].module;
492         }
493       }
494     }
495     FREE(pd_mod_entries.iso_c);
496     FREE(pd_mod_entries.iso_fortran);
497     FREE(usedb.base);
498     usedb.base = NULL;
499     usedb.sz = 0;
500     usedb.avl = NO_MODULE;
501   }
502 
503   freearea(USE_AREA);
504 }
505 
506 static int
find_def_in_most_recent_scope(int sptr,int save_sem_scope_level)507 find_def_in_most_recent_scope(int sptr, int save_sem_scope_level)
508 {
509   int sptr1;
510   SCOPESTACK *scope;
511 
512   for (sptr1 = first_hash(sptr); sptr1; sptr1 = HASHLKG(sptr1)) {
513     if (NMPTRG(sptr1) != NMPTRG(sptr))
514       continue;
515     if (STYPEG(sptr1) == ST_ALIAS && aliased_sym_visible(sptr1)) {
516       PRIVATEP(sptr1, 0);
517       HIDDENP(SYMLKG(sptr1), 0);
518     }
519     if (STYPEG(sptr1) == ST_ALIAS) {
520       if (PRIVATEG(sptr1))
521         continue;
522     } else if (HIDDENG(sptr1)) {
523       continue;
524     }
525 
526     switch (STYPEG(sptr1)) {
527     case ST_ISOC:
528     case ST_IEEEARITH:
529     case ST_CRAY:
530       /* predefined symbol, but not active in this routine */
531       continue;
532     case ST_MEMBER:
533       /* can't rename a member name */
534       continue;
535     default:;
536     }
537 
538     scope = curr_scope();
539     while ((scope = next_scope_sptr(scope, SCOPEG(sptr1))) != 0) {
540       int ng;
541       int scopelevel = get_scope_level(scope);
542       if (scopelevel < save_sem_scope_level) {
543         break;
544       }
545       /* FS#14884  If sptr1 is ST_ALIAS then the PRIVATE
546        * flag is not valid.  Look at the PRIVATE flag of the
547        * symbol the alias points to.
548        */
549       ng = sptr1;
550       while (STYPEG(ng) == ST_ALIAS && SYMLKG(ng) &&
551              NMPTRG(SYMLKG(ng)) == NMPTRG(sptr)) {
552         ng = SYMLKG(ng);
553       }
554       /* is the symbol visible in this scope: i.e. not on except list or
555           in private USE or a private module variable */
556       if (!is_except_in_scope(scope, sptr1) &&
557           !is_private_in_scope(scope, sptr1) &&
558           (STYPEG(ng) == ST_USERGENERIC || !PRIVATEG(ng))) {
559         return sptr1;
560       }
561     }
562   }
563   return NOSYM;
564 }
565 
566 static void
apply_use(MODULE_ID m_id)567 apply_use(MODULE_ID m_id)
568 {
569   int save_sem_scope_level, exceptlist, onlylist;
570   RENAME *pr;
571   FILE *use_fd;
572   USED *used = &usedb.base[m_id];
573   char *use_file_name = used->fullname;
574   SPTR sptr;
575 
576   if (DBGBIT(0, 0x10000))
577     fprintf(gbl.dbgfil, "Open module file: %s\n", use_file_name);
578   use_fd = fopen(use_file_name, "r");
579   /* -M option:  Print list of include files to stdout */
580   /* -MD option:  Print list of include files to file <program>.d */
581   if (sem.which_pass == 0 && ((XBIT(123, 2) || XBIT(123, 8)))) {
582     if (gbl.dependfil == NULL) {
583       if ((gbl.dependfil = tmpf("a")) == NULL)
584         errfatal(5);
585     } else
586       fprintf(gbl.dependfil, "\\\n  ");
587     if (!XBIT(123, 0x40000))
588       fprintf(gbl.dependfil, "%s ", use_file_name);
589     else
590       fprintf(gbl.dependfil, "\"%s\" ", use_file_name);
591   }
592   if (use_fd == NULL) {
593     set_exitcode(19);
594     if (XBIT(0, 0x20000000))
595       erremit(0);
596     error(4, 0, gbl.lineno, "Unable to open MODULE file",
597           SYMNAME(used->module));
598     return;
599   }
600   /* save this so we can tell what new symbols were added below */
601   save_sem_scope_level = sem.scope_level;
602   SCOPEP(used->module, 0);
603   /* Use INCLUDE_PRIVATES, parent privates are visible to inherited submodules.*/
604   used->module = import_module(use_fd, use_file_name, used->module,
605                                INCLUDE_PRIVATES, save_sem_scope_level);
606   DINITP(used->module, TRUE);
607   dbg_dump("apply_use", 0x2000);
608 
609   if ((seen_contains && sem.mod_cnt) || gbl.internal > 1 || sem.interface) {
610     /*
611        adjust symbol visibility if module has renames and processing a (module
612        or subroutine)
613        contained subroutine or a subroutine interface
614     */
615     adjust_symbol_accessibility(used->module);
616   }
617 
618   /* mark syms that are not accessible based on the USE ONLY list */
619   /* step1: set up NOT_IN_USEONLYP flags to 1 for all syms from the used module */
620   if (used->rename) {
621     for (sptr = stb.firstusym; sptr < stb.stg_avail; ++sptr) {
622       if (SCOPEG(sptr) == used->module)
623         NOT_IN_USEONLYP(sptr, 1);
624     }
625   }
626 
627   exceptlist = 0;
628   onlylist = 0;
629   for (pr = used->rename; pr != NULL; pr = pr->next) {
630     SPTR newglobal;
631     SPTR ng = 0;
632     SPTR oldglobal = pr->global;
633     SPTR oldlocal = pr->local;
634     char *name = SYMNAME(pr->global);
635 
636     if (pr->complete) {
637       /* already found as an iso_c intrinsic */
638       continue;
639     }
640 
641     newglobal = find_def_in_most_recent_scope(pr->global, save_sem_scope_level);
642 
643     /* mark syms that are not accessible based on the USE ONLY list */
644     /* step2: reverse NOT_IN_USEONLYP flag to 0 for syms on the USE ONLY list*/
645     for (sptr = stb.firstusym; sptr < stb.stg_avail; ++sptr) {
646       if (sptr == newglobal && SCOPEG(sptr) == used->module)
647         NOT_IN_USEONLYP(sptr, 0);
648     }
649 
650     if (newglobal > NOSYM) {
651       /* look for generic with same name */
652       ng = newglobal;
653       while ((STYPEG(ng) == ST_ALIAS || STYPEG(ng) == ST_MODPROC) &&
654              SYMLKG(ng) && NMPTRG(SYMLKG(ng)) == NMPTRG(newglobal)) {
655         ng = SYMLKG(ng);
656       }
657       if (STYPEG(ng) == ST_PROC && GSAMEG(ng) &&
658           SCOPEG(GSAMEG(ng)) == SCOPEG(newglobal)) {
659         /* generic with same name as specific, use the generic */
660         newglobal = GSAMEG(ng);
661       }
662     }
663 
664     if (newglobal <= NOSYM || newglobal < stb.firstosym ||
665         STYPEG(newglobal) == ST_UNKNOWN) {
666       if (!sem.which_pass)
667         continue;
668       error(84, 3, pr->lineno, name, "- not public entity of module");
669       IGNOREP(newglobal, 1);
670       continue;
671     }
672 
673     if (newglobal != oldglobal && STYPEG(oldglobal) == ST_UNKNOWN) {
674       /* ignore the fake symbol added by the 'use' clause */
675       if (pr->local) {
676         IGNOREP(oldglobal, 1);
677         HIDDENP(oldglobal, 1);
678       } else {
679         pr->local = oldglobal;
680       }
681     }
682     if (STYPEG(newglobal) == ST_MODPROC && SYMLKG(newglobal))
683       newglobal = SYMLKG(newglobal);
684     pr->global = newglobal;
685     gbl.lineno = pr->lineno;
686     if (!pr->local) {
687       pr->local = insert_sym(pr->global);
688     } else if (STYPEG(pr->local) != ST_UNKNOWN) {
689       pr->local = insert_sym(pr->local);
690     }
691     SCOPEP(pr->local, stb.curr_scope);
692     IGNOREP(pr->local, 0);
693     if (!oldlocal)
694       DCLDP(pr->local, 1); /* declared, not renamed */
695     if (STYPEG(ng /*pr->global*/) == ST_OPERATOR) {
696       STYPEP(pr->local, ST_OPERATOR);
697       INKINDP(pr->local, INKINDG(pr->global));
698       PDNUMP(pr->local, PDNUMG(pr->global));
699       copy_specifics(ng, pr->local);
700     } else if (STYPEG(ng /*pr->global*/) == ST_USERGENERIC && !GTYPEG(ng)) {
701       if (NMPTRG(pr->local) == NMPTRG(pr->global)) {
702         STYPEP(pr->local, ST_ALIAS);
703         SYMLKP(pr->local, pr->global);
704       } else {
705         STYPEP(pr->local, ST_USERGENERIC);
706         copy_specifics(ng, pr->local);
707         IGNOREP(SYMLKG(pr->global), 1);
708       }
709     } else {
710       STYPEP(pr->local, ST_ALIAS);
711       if (STYPEG(pr->global) == ST_ALIAS) {
712         SYMLKP(pr->local, SYMLKG(pr->global));
713         IGNOREP(pr->global, 1);
714       } else {
715         SYMLKP(pr->local, pr->global);
716       }
717     }
718     if (used->unrestricted) {
719       /* add the original module symbol to its except list */
720       exceptlist = add_symitem(pr->global, exceptlist);
721     } else {
722       onlylist = add_symitem(pr->global, onlylist);
723     }
724   }
725   if (used->unrestricted) {
726     /* add this stuff to the exception list */
727     int nexte, e;
728     for (e = exceptlist; e; e = nexte) {
729       SPTR sptr = SYMI_SPTR(e);
730       SCOPESTACK *scope = next_scope_sptr(curr_scope(), SCOPEG(sptr));
731       nexte = SYMI_NEXT(e);
732       if (get_scope_level(scope) >= save_sem_scope_level) {
733         SYMI_NEXT(e) = scope->except;
734         scope->except = e;
735         if (STYPEG(sptr) == ST_ALIAS && STYPEG(SYMLKG(sptr)) == ST_PROC) {
736           /* hide original alias for a renamed subprogram */
737           int s;
738           PRIVATEP(sptr, 1); /* hide original alias for a renamed subprogram */
739           HIDDENP(SYMLKG(sptr), 1); /* hide subprogram itself,
740                                          doesn't seem to be necessary */
741           for (s = first_hash(sptr); s; s = HASHLKG(s)) {
742             if (STYPEG(s) == ST_MODPROC && SYMLKG(s) == sptr) {
743               HIDDENP(s, 1); /* hide any associated ST_MODPROC */
744               break;
745             }
746           }
747         }
748       }
749     }
750     update_use_tree_exceptions();
751   } else {
752     /* the SCOPE_USE will be pushed at the scope
753      * level of the old SCOPE_NORMAL */
754     SCOPESTACK *scope = curr_scope();
755     while ((scope = next_scope(scope)) != 0 &&
756            get_scope_level(scope) >= save_sem_scope_level) {
757       int o, nexto;
758       scope->Private = TRUE;
759       for (o = onlylist; o; o = nexto) {
760         nexto = SYMI_NEXT(o);
761         if (SCOPEG(SYMI_SPTR(o)) == scope->sptr) {
762           SYMI_NEXT(o) = scope->only;
763           scope->only = add_only(o, save_sem_scope_level);
764         }
765       }
766     }
767   }
768   fclose(use_fd);
769 }
770 
771 /* predefined  processing for the iso_c module only */
772 static void
add_predefined_isoc_module(void)773 add_predefined_isoc_module(void)
774 {
775   int i;
776   RENAME *pr;
777 
778   if (usedb.base[ISO_C_MOD].unrestricted) { /* do all */
779     SPTR sptr;
780     for (i = 0; (sptr = pd_mod_entries.iso_c[i]) != 0; ++i) {
781       if (strcmp(SYMNAME(sptr), "c_sizeof") == 0) {
782         STYPEP(sptr, ST_PD);
783       } else {
784         STYPEP(sptr, ST_INTRIN);
785       }
786     }
787   }
788 
789   for (pr = usedb.base[ISO_C_MOD].rename; pr != NULL; pr = pr->next) {
790     SPTR sptr = pr->global;
791     SPTR found = get_iso_c_entry(SYMNAME(pr->global));
792     if (found) {
793       pr->global = found;
794       pr->complete = 1;
795       if (pr->local) {
796         gbl.lineno = pr->lineno;
797         pr->local = declsym(pr->local, ST_ALIAS, TRUE);
798         SYMLKP(pr->local, pr->global);
799       }
800       /* Hide the symbol created when the  ST_ISOC  is lex'd.
801        * NOTE that get_iso_c_entry() changes ST_ISOC to ST_INTRIN
802        */
803       /* c_sizeof is the only symbol in the ISO_C_MOD that is a
804        * ST_PD (predefined) so it must be handled explicitly.
805        */
806       if ((STYPEG(found) == ST_INTRIN ||
807            (STYPEG(found) == ST_PD &&
808             strcmp(SYMNAME(pr->global), "c_sizeof") == 0)) &&
809           sptr != found && STYPEG(sptr) == ST_UNKNOWN) {
810         pop_sym(sptr);
811         IGNOREP(sptr, 1); /* and do not send to .mod file */
812       }
813     }
814   }
815 }
816 
817 /* predefined  processing for the iso_fortran_env module only */
818 static void
add_predefined_iso_fortran_env_module(void)819 add_predefined_iso_fortran_env_module(void)
820 {
821   RENAME *pr;
822 
823   if (usedb.base[ISO_FORTRAN_ENV].unrestricted) { /* do all */
824     int i;
825     SPTR sptr;
826     for (i = 0; (sptr = pd_mod_entries.iso_fortran[i]) != 0; ++i) {
827       if (STYPEG(sptr) == ST_ISOFTNENV)
828         STYPEP(sptr, ST_PD);
829     }
830   }
831 
832   for (pr = usedb.base[ISO_FORTRAN_ENV].rename; pr != NULL; pr = pr->next) {
833     SPTR sptr = pr->global;
834     SPTR found = get_iso_fortran_entry(SYMNAME(pr->global));
835     if (found) {
836       pr->global = found;
837       pr->complete = 1;
838       if (pr->local) {
839         gbl.lineno = pr->lineno;
840         pr->local = declsym(pr->local, ST_ALIAS, TRUE);
841         SYMLKP(pr->local, pr->global);
842       }
843       /* Hide the symbol created when the  ST_ISOFTNEV  is lex'd.
844        * NOTE that get_iso_fortran_entry() changes ST_ISOFTNEV to ST_PD
845        */
846       if (STYPEG(found) == ST_PD && sptr != found &&
847           STYPEG(sptr) == ST_UNKNOWN) {
848         pop_sym(sptr);
849         IGNOREP(sptr, 1); /* and do not send to .mod file */
850       }
851     }
852   }
853 }
854 
855 void
add_isoc_intrinsics(void)856 add_isoc_intrinsics(void)
857 {
858   int first, last, size;
859   int i;
860   int sptr;
861 
862   iso_c_lib_stat(&first, &last, ST_ISOC);
863   size = last - first + 1;
864   for (i = 0; i < size; i++) {
865     sptr = first++;
866     if (STYPEG(sptr) == ST_ISOC) {
867       STYPEP(sptr, ST_INTRIN);
868     }
869   }
870 }
871 
872 static void
add_predefined_ieeearith_module(void)873 add_predefined_ieeearith_module(void)
874 {
875   SPTR sptr;
876   RENAME *pr;
877   int found;
878 
879   found = 0;
880   if (usedb.base[IEEE_ARITH_MOD].unrestricted) { /* do all */
881     found = get_ieee_arith_intrin("ieee_selected_real_kind");
882   }
883   for (pr = usedb.base[IEEE_ARITH_MOD].rename; pr != NULL; pr = pr->next) {
884     sptr = pr->global;
885     if (strcmp(SYMNAME(sptr), "ieee_selected_real_kind") == 0) {
886       found = get_ieee_arith_intrin("ieee_selected_real_kind");
887 #if DEBUG
888       assert(found, "ieee_arithmetic routine not found", sptr, 3);
889 #endif
890       pr->global = found;
891       pr->complete = 1;
892       if (pr->local) {
893         gbl.lineno = pr->lineno;
894         pr->local = declsym(pr->local, ST_ALIAS, TRUE);
895         SYMLKP(pr->local, pr->global);
896       }
897       /* Hide the symbol created when the  ST_IEEEARITH  is lex'd.
898        */
899       pop_sym(sptr);
900       IGNOREP(sptr, 1); /* and do not send to .mod file */
901     }
902   }
903   if (found) {
904     STYPEP(found, ST_PD);
905     SCOPEP(found, 0);
906   }
907 }
908 
909 /** \brief Begin processing a USE statement.
910  * \a use - sym ptr of module identifer in use statement
911  * Find or create an entry in usedb for it and set 'module_id' to the index.
912  */
913 void
open_module(SPTR use)914 open_module(SPTR use)
915 {
916   const char *name;
917   char *fullname;
918   char *modu_file_name;
919 
920   if (STYPEG(use) != ST_MODULE && STYPEG(use) != ST_UNKNOWN &&
921       SCG(use) != SC_NONE) {
922     /* a variable of this name had been declared, perhaps in an enclosing
923      * subprogram */
924     SPTR sptr;
925     NEWSYM(sptr);
926     NMPTRP(sptr, NMPTRG(use));
927     SYMLKP(sptr, NOSYM);
928     use = sptr;
929   }
930   name = SYMNAME(use);
931 
932   for (module_id = FIRST_MODULE; module_id < usedb.avl; module_id++)
933     if (strcmp(SYMNAME(usedb.base[module_id].module), name) == 0)
934       return;
935 
936 #define MAX_FNAME_LEN 258
937 
938   fullname = getitem(8, MAX_FNAME_LEN + 1);
939   modu_file_name = getitem(8, strlen(name) + strlen(MOD_SUFFIX) + 1);
940   strcpy(modu_file_name, name);
941   convert_2dollar_signs_to_hyphen(modu_file_name);
942   strcat(modu_file_name, MOD_SUFFIX);
943   if (!get_module_file_name(modu_file_name, fullname, MAX_FNAME_LEN)) {
944     set_exitcode(19);
945     if (XBIT(0, 0x20000000))
946       erremit(0);
947     error(4, 0, gbl.lineno, "Unable to open MODULE file", modu_file_name);
948     return;
949   }
950   if (use < stb.firstusym) {
951     /* if module has the same name as some predefined thing */
952     use = insert_sym(use);
953   }
954   if (strcmp(name, "iso_c_binding") == 0) {
955     module_id = ISO_C_MOD;
956   } else if (strcmp(name, "ieee_arithmetic") == 0) {
957     module_id = IEEE_ARITH_MOD;
958   } else if (strcmp(name, "ieee_arithmetic_la") == 0) {
959     module_id = IEEE_ARITH_MOD;
960   } else if (strcmp(name, "ieee_features") == 0) {
961     module_id = IEEE_FEATURES_MOD;
962   } else if (strcmp(name, "iso_fortran_env") == 0) {
963     module_id = ISO_FORTRAN_ENV;
964   } else {
965     module_id = usedb.avl++;
966   }
967   NEED(usedb.avl, usedb.base, USED, usedb.sz, usedb.sz + 8);
968   usedb.base[module_id].module = use;
969   usedb.base[module_id].unrestricted = FALSE;
970   usedb.base[module_id].submodule = FALSE;
971   usedb.base[module_id].rename = NULL;
972   usedb.base[module_id].fullname = fullname;
973 
974   if (module_id == ISO_C_MOD) {
975     int i;
976     int first, last;
977     /* add the predefined intrinsic functions c_loc, etc */
978     iso_c_lib_stat(&first, &last, ST_ISOC);
979     /* +1 for c_sizeof, +1 for 0 at end: */
980     NEW(pd_mod_entries.iso_c, SPTR, last - first + 3);
981     for (i = 0; first <= last; ++i, ++first) {
982       pd_mod_entries.iso_c[i] = first;
983     }
984     /* c_sizeof is from F2008 and is a  PD rather than a ST_ISOC */
985     pd_mod_entries.iso_c[i++] = lookupsymbol("c_sizeof");
986     pd_mod_entries.iso_c[i] = 0;
987   }
988   if (module_id == ISO_FORTRAN_ENV) {
989     if (pd_mod_entries.iso_fortran)
990       return;
991     NEW(pd_mod_entries.iso_fortran, SPTR, 3);
992     pd_mod_entries.iso_fortran[0] = lookupsymbol("compiler_options");
993     pd_mod_entries.iso_fortran[1] = lookupsymbol("compiler_version");
994     pd_mod_entries.iso_fortran[2] = 0;
995   }
996   /*
997    * at this point, there is not similar processing for IEEE_ARITH_MOD
998    * as ISO_C_MOD.  Only one ieee_arithmetic routine actually needs to
999    * be represented as an intrinsic/predeclared.  That routine is
1000    * ieee_selected_real_kind; so, there is no need to have a sequence
1001    * of 'pd_mod_entries' entries for the ieee_arithmetic module.
1002    */
1003 }
1004 
1005 static SPTR
find_entry(const SPTR * entries,const char * name)1006 find_entry(const SPTR *entries, const char *name)
1007 {
1008   if (entries != 0) {
1009     SPTR sptr;
1010     for (; (sptr = *entries) != 0; ++entries) {
1011       if (strcmp(SYMNAME(sptr), name) == 0) {
1012         return sptr;
1013       }
1014     }
1015   }
1016   return 0;
1017 }
1018 
1019 static SPTR
get_iso_c_entry(const char * name)1020 get_iso_c_entry(const char *name)
1021 {
1022   SPTR sptr = find_entry(pd_mod_entries.iso_c, name);
1023   if (sptr != 0 && STYPEG(sptr) == ST_ISOC) {
1024     if (strcmp(name, "c_sizeof") == 0) {
1025       STYPEP(sptr, ST_PD);
1026     } else {
1027       STYPEP(sptr, ST_INTRIN);
1028     }
1029   }
1030   return sptr;
1031 }
1032 
1033 static SPTR
get_iso_fortran_entry(const char * name)1034 get_iso_fortran_entry(const char *name)
1035 {
1036   SPTR sptr = find_entry(pd_mod_entries.iso_fortran, name);
1037   if (sptr != 0 && STYPEG(sptr) == ST_ISOFTNENV)
1038     STYPEP(sptr, ST_PD);
1039   return sptr;
1040 }
1041 
1042 void
close_module(void)1043 close_module(void)
1044 {
1045 }
1046 
1047 /* ------------------------------------------------------------------ */
1048 /*   MODULE & CONTAINS statements - create module file */
1049 
1050 static int modu_sym = 0;
1051 static FILE *outfile;
1052 static FILE *single_outfile = NULL;
1053 static char *single_outfile_name = NULL;
1054 static char *single_outfile_index_name = NULL;
1055 static char modu_name[MAXIDLEN + 1];
1056 static int mod_lineno;
1057 
1058 #ifdef HOST_WIN
1059 #define long_t long long
1060 #define LLF "%lld"
1061 #else
1062 #define long_t long
1063 #define LLF "%ld"
1064 #endif
1065 typedef struct mod_index {
1066   struct mod_index *next;
1067   char *module_name;
1068   long_t offset;
1069 } mod_index;
1070 static mod_index *mod_index_list = NULL;
1071 
1072 typedef struct {
1073   int firstc; /* first character in range */
1074   int lastc;  /* last character in range */
1075   int dtype;  /* implicit dtype pointer: 0 => NONE */
1076 } IMPL;
1077 
1078 static struct {
1079   IMPL *base;
1080   int avl;
1081   int sz;
1082 } impl;
1083 
1084 /*
1085  * save the name to use for the combined .mod file
1086  */
1087 void
mod_combined_name(char * name)1088 mod_combined_name(char *name)
1089 {
1090   single_outfile_name = name;
1091 } /* mod_combined_name */
1092 
1093 /*
1094  * save the name to use for the combined module index file
1095  */
1096 void
mod_combined_index(char * name)1097 mod_combined_index(char *name)
1098 {
1099   single_outfile_index_name = name;
1100 } /* mod_combined_index */
1101 
1102 /* Begin processing a module. Put the name of the module in modu_name and return
1103  * the new ST_MODULE symbol.
1104  */
1105 SPTR
begin_module(SPTR id)1106 begin_module(SPTR id)
1107 {
1108   strcpy(modu_name, SYMNAME(id));
1109   modu_sym = declsym(id, ST_MODULE, TRUE);
1110   DCLDP(modu_sym, 1);
1111   FUNCLINEP(modu_sym, gbl.lineno);
1112 
1113   mod_lineno = gbl.lineno;
1114   seen_contains = FALSE;
1115   outfile = NULL;  /* only create if error free */
1116   gbl.currsub = 0; /* ==> module */
1117   gbl.currmod = modu_sym;
1118   impl.sz = 16;
1119   NEW(impl.base, IMPL, impl.sz);
1120   impl.avl = 0;
1121   sem.mod_dllexport = FALSE;
1122   init_use_tree();
1123   return modu_sym;
1124 }
1125 
1126 /* Begin processing a submodule:
1127  *   SUBMODULE ( <ancestor_module> [ : <parent_submodule> ] ) <id>
1128  * Return the sptr for the parent (module or submodule) thru parent_sptr
1129  * and handling like a normal module, returning the sptr for the new ST_MODULE.
1130  */
1131 SPTR
begin_submodule(SPTR id,SPTR ancestor_mod,SPTR parent_submod,SPTR * parent)1132 begin_submodule(SPTR id, SPTR ancestor_mod, SPTR parent_submod, SPTR *parent)
1133 {
1134   SPTR submod;
1135   if (ancestor_mod < stb.firstusym) {
1136     /* if the ancestor module has the same name as some predefined thing */
1137     ancestor_mod = insert_sym(ancestor_mod);
1138   }
1139   if (parent_submod <= NOSYM) {
1140     *parent = ancestor_mod;
1141   } else {
1142     if (strcmp(SYMNAME(parent_submod), SYMNAME(id)) == 0) {
1143       error(4, ERR_Severe, gbl.lineno, "SUBMODULE cannot be its own parent -",
1144             SYMNAME(id));
1145     }
1146     *parent = get_submod_sym(ancestor_mod, parent_submod);
1147     ANCESTORP(*parent, ancestor_mod);
1148   }
1149   submod = begin_module(get_submod_sym(ancestor_mod, id));
1150   ANCESTORP(submod, ancestor_mod);
1151   return submod;
1152 }
1153 
1154 /* Return the symbol for a submodule. It is qualified with the name of
1155  * the module that it is a submodule of.
1156  */
1157 static SPTR
get_submod_sym(SPTR ancestor_module,SPTR submodule)1158 get_submod_sym(SPTR ancestor_module, SPTR submodule)
1159 {
1160   return getsymf("%s$$%s", SYMNAME(ancestor_module), SYMNAME(submodule));
1161 }
1162 
1163 LOGICAL
get_seen_contains(void)1164 get_seen_contains(void)
1165 {
1166   return seen_contains;
1167 }
1168 
1169 /* first character in range */
1170 /* last character in range */
1171 /* implicit dtype pointer: 0 => NONE */
1172 void
mod_implicit(int firstc,int lastc,int dtype)1173 mod_implicit(int firstc, int lastc, int dtype)
1174 {
1175   int i;
1176 
1177   i = impl.avl++;
1178   NEED(impl.avl, impl.base, IMPL, impl.sz, impl.sz + 16);
1179   impl.base[i].firstc = firstc;
1180   impl.base[i].lastc = lastc;
1181   impl.base[i].dtype = dtype;
1182 }
1183 
1184 static void
handle_mod_syms_dllexport(void)1185 handle_mod_syms_dllexport(void)
1186 {
1187   int sptr;
1188 
1189   if (!sem.mod_dllexport) {
1190     return;
1191   }
1192 
1193   for (sptr = stb.firstusym; sptr < stb.stg_avail; ++sptr) {
1194     switch (STYPEG(sptr)) {
1195     case ST_MODULE:
1196       if (sptr == gbl.currmod) {
1197         DLLP(sptr, DLL_EXPORT);
1198       }
1199       break;
1200     case ST_ENTRY:
1201       if (ENCLFUNCG(sptr) == gbl.currmod) {
1202         DLLP(sptr, DLL_EXPORT);
1203       }
1204       break;
1205     case ST_PROC:
1206       if (ENCLFUNCG(sptr) == gbl.currmod && INMODULEG(sptr)) {
1207         DLLP(sptr, DLL_EXPORT);
1208       }
1209       break;
1210     case ST_VAR:
1211     case ST_ARRAY:
1212       if (SCG(sptr) == SC_CMBLK && SCOPEG(sptr) == gbl.currmod &&
1213           HCCSYMG(CMBLKG(sptr))) {
1214         DLLP(sptr, DLL_EXPORT);
1215         break;
1216       }
1217       break;
1218     default:;
1219     }
1220   }
1221 }
1222 
1223 void
begin_contains(void)1224 begin_contains(void)
1225 {
1226   if (seen_contains) {
1227     errsev(70);
1228     return;
1229   }
1230   seen_contains = TRUE;
1231   sem.mod_cnt = 2; /* ensure semfin() preforms all of its processing  */
1232   save_module_state1();
1233   fix_module_common();
1234   handle_mod_syms_dllexport();
1235 
1236   save_module_state2();
1237   save_implicit(FALSE);
1238   sem.mod_cnt = 1;
1239 }
1240 
1241 void
end_module(void)1242 end_module(void)
1243 {
1244   int sptr;
1245 
1246   if (!seen_contains) {
1247     sem.mod_cnt = 2;
1248     if (sem.accl.type == 'v') {
1249       /* default is private */
1250       sem.mod_public_flag = 0;
1251     } else {
1252       sem.mod_public_flag = 1;
1253     }
1254   }
1255   if (sem.mod_cnt == 2)
1256     FREE(impl.base);
1257   if (modu_sym == 0) {
1258     if (outfile != NULL && sem.mod_cnt == 2) {
1259       fclose(outfile);
1260       outfile = NULL;
1261     }
1262     goto exit;
1263   }
1264   export_public_used_modules(sem.scope_level);
1265 
1266   if (!seen_contains) {
1267     fix_module_common();
1268     handle_mod_syms_dllexport();
1269   }
1270 
1271   /* When use-associated, the ST_MODULE is turned into a ST_PROC. So,
1272    * NEEDMOD distinguishes between an ST_PROC created from a ST_MODULE
1273    * vs a real procedure.  When NEEDMOD is set, Fortran backend will not put
1274    * the ST_PROC in the 'ureferenced external' category.
1275    */
1276   NEEDMODP(modu_sym, 1);
1277   if (astb.df != NULL || dinit_ftell() > 0) {
1278     /*
1279      * Older versions of the compiler unconditionally set NEEDMOD.  The new
1280      * behavior of the backend is to generate a hard reference to the
1281      * global module name if NEEDMOD is set.  Need a method to distinguish
1282      * between the old and new interpretations of NEEDMOD.  The older
1283      * compilers never set the TYPD flag for ST_MODULEs!
1284      */
1285     TYPDP(modu_sym, 1);
1286   }
1287 
1288   export_all();
1289   if (seen_contains)
1290     gbl.currsub = 0;
1291 
1292   if (outfile != NULL && sem.mod_cnt == 2) {
1293     fclose(outfile);
1294     outfile = NULL;
1295   }
1296   if (sem.which_pass == 0 && ((XBIT(123, 2) || XBIT(123, 8)))) {
1297     if (gbl.moddependfil == NULL) {
1298       if ((gbl.moddependfil = tmpf("a")) == NULL)
1299         errfatal(5);
1300     }
1301     if (!XBIT(123, 0x40000)) {
1302       fprintf(gbl.moddependfil, "%s%s : ", modu_name, MOD_SUFFIX);
1303       fprintf(gbl.moddependfil, "%s\n", gbl.src_file);
1304     } else {
1305       fprintf(gbl.moddependfil, "\"%s%s\" : ", modu_name, MOD_SUFFIX);
1306       fprintf(gbl.moddependfil, "\"%s\"\n", gbl.src_file);
1307     }
1308   }
1309   modu_sym = 0;
1310   exportb.hpf_library = FALSE;
1311   exportb.hpf_local_library = FALSE;
1312   exportb.iso_c_library = FALSE;
1313   exportb.iso_fortran_env_library = FALSE;
1314   exportb.ieee_arith_library = FALSE;
1315 
1316   /* check for undefined module subprograms */
1317   for (sptr = stb.firstusym; sptr < stb.stg_avail; ++sptr) {
1318     if (!IGNOREG(sptr) && STYPEG(sptr) == ST_MODPROC && SYMLKG(sptr) == 0) {
1319       error(155, 2, gbl.lineno, "MODULE PROCEDURE not defined:", SYMNAME(sptr));
1320     }
1321   }
1322 
1323 exit:
1324   init_use_tree();
1325 }
1326 
1327 /* ------------------------------------------------------------------ */
1328 /*   Write .mod file  */
1329 
1330 /*  getitem area for module temp storage; pick an area not used by
1331  *  semant.
1332  */
1333 
1334 static int
make_module_common(int idx,int private,int threadprivate,int device,int isconstant,int iscopyin,int islink)1335 make_module_common(int idx, int private, int threadprivate, int device,
1336                    int isconstant, int iscopyin, int islink)
1337 {
1338   static char sfx[3];
1339   char modcm_name[MAXIDLEN + 2];
1340   int modcm;
1341   if (idx <= 9) {
1342     sfx[0] = '0' + idx;
1343     sfx[1] = 0;
1344   } else if (idx <= 19) {
1345     sfx[0] = '1';
1346     sfx[1] = '0' + (idx - 10);
1347     sfx[2] = 0;
1348   } else {
1349     sfx[0] = '2';
1350     sfx[1] = '0' + (idx - 20);
1351     sfx[2] = 0;
1352   }
1353   if (!XBIT(58, 0x80000)) {
1354     modcm_name[0] = '_';
1355     strcpy(modcm_name + 1, modu_name);
1356   } else {
1357     strcpy(modcm_name, modu_name);
1358   }
1359   modcm = get_next_sym(modcm_name, sfx);
1360   STYPEP(modcm, ST_CMBLK);
1361   SIZEP(modcm, 0);
1362   SYMLKP(modcm, gbl.cmblks);
1363   MODCMNP(modcm, 1);
1364   gbl.cmblks = modcm;
1365   PRIVATEP(modcm, private);
1366   THREADP(modcm, threadprivate);
1367 #ifdef DEVICEP
1368   if (device)
1369     DEVICEP(modcm, 1);
1370   if (isconstant) {
1371     CONSTANTP(modcm, 1);
1372   } else if (islink) {
1373     ACCLINKP(modcm, 1);
1374   } else if (iscopyin) {
1375     ACCCOPYINP(modcm, 1);
1376   }
1377 #endif
1378   CMEMFP(modcm, NOSYM);
1379   CMEMLP(modcm, NOSYM);
1380   if (flg.sequence)
1381     SEQP(modcm, 1);
1382   if (sem.mod_dllexport) {
1383     DLLP(modcm, DLL_EXPORT);
1384   }
1385   return modcm;
1386 } /* make_module_common */
1387 
1388 /* add a padding symbol with numeric or char type here */
1389 static int
add_padding(int sptr,int dtype,ISZ_T padsize,int cmidx)1390 add_padding(int sptr, int dtype, ISZ_T padsize, int cmidx)
1391 {
1392   int newdtype, padding;
1393   /* make a dummy symbol */
1394   padding = get_next_sym(SYMNAME(sptr), "pad");
1395   if (DTY(dtype) == TY_CHAR || DTY(dtype) == TY_NCHAR) {
1396     newdtype = get_type(2, DTY(dtype), mk_cval(padsize, DT_INT4));
1397     STYPEP(padding, ST_VAR);
1398   } else {
1399     newdtype = get_array_dtype(1, dtype);
1400     ADD_LWAST(newdtype, 0) = ADD_LWBD(newdtype, 0) = mk_cval(1, DT_INT);
1401     ADD_UPAST(newdtype, 0) = ADD_UPBD(newdtype, 0) = ADD_EXTNTAST(newdtype, 0) =
1402         mk_cval(padsize, DT_INT);
1403     ADD_NUMELM(newdtype) = mk_cval(padsize, DT_INT);
1404     STYPEP(padding, ST_ARRAY);
1405   }
1406   SCP(padding, SC_LOCAL);
1407   DTYPEP(padding, newdtype);
1408   DCLDP(padding, 1);
1409   SEQP(padding, 1);
1410 #ifdef DEVICEG
1411   DEVICEP(padding, DEVICEG(sptr));
1412   MANAGEDP(padding, MANAGEDG(sptr));
1413   ACCCREATEP(padding, ACCCREATEG(sptr));
1414   ACCCOPYINP(padding, ACCCOPYING(sptr));
1415   ACCLINKP(padding, ACCLINKG(sptr));
1416   CONSTANTP(padding, CONSTANTG(sptr));
1417 #endif
1418   add_to_common(cmidx, padding, 0);
1419   return padding;
1420 } /* add_padding */
1421 
1422 #ifdef DEVICEG
1423 /*
1424  * if this symbol is in an equivalence statement,
1425  * propagate the DEVICEG, MANAGEDG, ACCCREATEG, ACCCOPYING, ACCRESIDENTG,
1426  * ACCLINKG,
1427  * and CONSTANTG flags from this symbol to any symbols in its overlap list,
1428  * and from any symbol in the overlap list to this symbol.
1429  */
1430 static int
propagate_device_flags(int sptr)1431 propagate_device_flags(int sptr)
1432 {
1433   if (SOCPTRG(sptr)) {
1434     int dev = DEVICEG(sptr);
1435     int managed = MANAGEDG(sptr);
1436     int acccreate = ACCCREATEG(sptr);
1437     int acccopyin = ACCCOPYING(sptr);
1438     int acclink = ACCLINKG(sptr);
1439     int cnstant = CONSTANTG(sptr);
1440     int p;
1441     for (p = SOCPTRG(sptr); p; p = SOC_NEXT(p)) {
1442       int ovsptr = SOC_SPTR(p);
1443       if (DEVICEG(ovsptr))
1444         dev = 1;
1445       if (MANAGEDG(ovsptr))
1446         managed = 1;
1447       if (ACCCREATEG(ovsptr))
1448         acccreate = 1;
1449       if (ACCCOPYING(ovsptr))
1450         acccopyin = 1;
1451       if (ACCLINKG(ovsptr))
1452         acclink = 1;
1453       if (CONSTANTG(ovsptr))
1454         cnstant = 1;
1455     }
1456     DEVICEP(sptr, dev);
1457     MANAGEDP(sptr, managed);
1458     ACCCREATEP(sptr, acccreate);
1459     ACCCOPYINP(sptr, acccopyin);
1460     ACCLINKP(sptr, acclink);
1461     CONSTANTP(sptr, cnstant);
1462     for (p = SOCPTRG(sptr); p; p = SOC_NEXT(p)) {
1463       int ovsptr = SOC_SPTR(p);
1464       DEVICEP(ovsptr, dev);
1465       MANAGEDP(ovsptr, managed);
1466       ACCCREATEP(ovsptr, acccreate);
1467       ACCCOPYINP(ovsptr, acccopyin);
1468       ACCLINKP(ovsptr, acclink);
1469       CONSTANTP(ovsptr, cnstant);
1470     }
1471   }
1472   return FALSE;
1473 } /* propagate_device_flags */
1474 #endif
1475 
1476 /*
1477  * module common combinations:
1478  *
1479  * not initd: pub-nonchar,  pub-char,  pub-long,  pub_threadprivate,
1480  *            priv-nonchar, priv-char, priv-long, priv_threadprivate,
1481  * initd    : pub-nonchar,  pub-char,  pub-long,  pub_threadprivate,
1482  *            priv-nonchar, priv-char, priv-long, priv_threadprivate,
1483  * device   : device, constant, copyin, link,
1484  *            threadprivate: device, constant, copyin, link
1485  * dev-initd: device, constant, device-threadprivate, constant-threadprivate
1486  * openacc create/resident data is treated like device data
1487  */
1488 static int mod_cmn[32];
1489 #define FIRST_DEV_COMMON 16
1490 #define LAST_DEV_COMMON 28
1491 static int
MOD_CMN_IDX(int xpriv,int xchar,int xlong,int xinitd,int thrd_priv,int xdev,int xconst,int xcopyin,int xlink)1492 MOD_CMN_IDX(int xpriv, int xchar, int xlong, int xinitd, int thrd_priv,
1493             int xdev, int xconst, int xcopyin, int xlink)
1494 {
1495   if ((xdev + xconst + xcopyin + xlink) == 0) {
1496     if (thrd_priv) /* don't separate int/char/long */
1497       return 4 * xpriv + 8 * xinitd + 3;
1498     return 4 * xpriv + xchar + 2 * xlong + 8 * xinitd;
1499   }
1500   if (xconst)
1501     return 16 + 1 + 2 * thrd_priv + 8 * xinitd;
1502   if (xlink)
1503     return 16 + 6 + 2 * thrd_priv;
1504   if (xcopyin)
1505     return 16 + 5 + 2 * thrd_priv;
1506   return 16 + 2 * thrd_priv + 8 * xinitd;
1507 }
1508 
1509 #define N_MOD_CMN sizeof(mod_cmn) / sizeof(int)
1510 static int mod_cmn_naln[N_MOD_CMN];
1511 
1512 typedef struct itemx { /* generic item record */
1513   int val;
1514   struct itemx *next;
1515 } ITEMX;
1516 static ITEMX *mdalloc_list;
1517 static ITEMX *pointer_list;
1518 
1519 static void
check_sc(int sptr)1520 check_sc(int sptr)
1521 {
1522   ITEMX *px;
1523   int dty;
1524   int ty, tysize;
1525   int acc;    /* access type: 0 = PUBLIC, 1 = PRIVATE */
1526   int chr;    /* 0 => non-character; 1 => character */
1527   int islong; /* 0 => not long; 1 => long */
1528   int initd;  /* 0 => not initd;  1 => initd */
1529   int idx, dev, con, link, cpyin;
1530 
1531   if (IGNOREG(sptr))
1532     return;
1533   switch (SCG(sptr)) {
1534   case SC_BASED:
1535   case SC_DUMMY:
1536     dty = DTYG(DTYPEG(sptr));
1537     if (XBIT(58, 0x10000) ||
1538         (dty != TY_DERIVED && dty != TY_CHAR && dty != TY_NCHAR)) {
1539       if (POINTERG(sptr) && !F90POINTERG(sptr) && MIDNUMG(sptr) &&
1540           SCG(MIDNUMG(sptr)) != SC_CMBLK) {
1541         /* process pointer variables later; a pointer variable's
1542          * associated variables need to placed in its own common
1543          * block.  Can't process here since they would be added
1544          * to the module's common block.
1545          */
1546         px = (ITEMX *)getitem(0, sizeof(ITEMX));
1547         px->val = sptr;
1548         px->next = pointer_list;
1549         pointer_list = px;
1550         /*
1551          * Give the pointer attribute precedence over module
1552          * allocatable.
1553          */
1554         MDALLOCP(sptr, 0);
1555       }
1556     }
1557     if (ALLOCATTRG(sptr)) {
1558       /* process module allocatable arrays later; a variable's
1559        * associated variables need to placed in its own common
1560        * block.  Can't process here since they would be added
1561        * to the module's common block.
1562        */
1563       px = (ITEMX *)getitem(0, sizeof(ITEMX));
1564       px->val = sptr;
1565       px->next = mdalloc_list;
1566       mdalloc_list = px;
1567       break;
1568     }
1569   case SC_CMBLK:
1570     MDALLOCP(sptr, 0);
1571     break;
1572   case SC_NONE:
1573     /* see if we should handle these pointer vars or pass them through */
1574     dty = DTYG(DTYPEG(sptr));
1575     if (XBIT(58, 0x10000) ||
1576         (dty != TY_DERIVED && dty != TY_CHAR && dty != TY_NCHAR)) {
1577       if (POINTERG(sptr) && !F90POINTERG(sptr)) {
1578         /* process pointer variables later; a pointer variable's
1579          * associated variables need to placed in its own common
1580          * block.  Can't process here since they would be added
1581          * to the module's common block.
1582          */
1583         px = (ITEMX *)getitem(0, sizeof(ITEMX));
1584         px->val = sptr;
1585         px->next = pointer_list;
1586         pointer_list = px;
1587         /*
1588          * Give the pointer attribute precedence over module
1589          * allocatable.
1590          */
1591         MDALLOCP(sptr, 0);
1592         break;
1593       }
1594       if (ALLOCG(sptr) && !F90POINTERG(sptr)) {
1595         /* process module allocatable arrays later; a variable's
1596          * associated variables need to placed in its own common
1597          * block.  Can't process here since they would be added
1598          * to the module's common block.
1599          */
1600         px = (ITEMX *)getitem(0, sizeof(ITEMX));
1601         px->val = sptr;
1602         px->next = mdalloc_list;
1603         mdalloc_list = px;
1604         break;
1605       }
1606     }
1607   /* else fall thru */
1608   default:
1609 #ifdef DEVICEG
1610     propagate_device_flags(sptr);
1611 #endif
1612     if (EQVG(sptr)) {
1613       /* don't add to module common, its equivalenced var will be */
1614       break;
1615     }
1616     dev = 0;
1617     cpyin = 0;
1618     link = 0;
1619 #ifdef DEVICEG
1620     if (DEVICEG(sptr) || MANAGEDG(sptr) || ACCCREATEG(sptr) ||
1621         ACCCOPYING(sptr) || ACCRESIDENTG(sptr))
1622       dev = 1;
1623     if (ACCCOPYING(sptr))
1624       cpyin = 1;
1625     if (ACCLINKG(sptr)) {
1626       dev = 1;
1627       link = 1;
1628     }
1629     con = CONSTANTG(sptr);
1630 #endif
1631     if (XBIT(57, 0x800000) && !dev && !con) {
1632       /* don't set this for device or constant commons? */
1633       if (DTY(DTYPEG(sptr)) == TY_ARRAY && !DESCARRAYG(sptr)) {
1634 #ifdef QALNP
1635         QALNP(sptr, 1); /* quad-word align */
1636 #endif
1637 #ifdef PDALNP
1638         PDALNP(sptr, 4); /* quad-word align */
1639 #endif
1640       }
1641     }
1642     ty = basedtype(sptr);
1643     if (ty == 0)
1644       return; /* don't add to module common */
1645     if (CFUNCG(sptr)) {
1646       SCP(sptr, SC_EXTERN);
1647       return; /* C visable module variable not
1648                            in common block */
1649     }
1650     tysize = size_of(ty);
1651     acc = PRIVATEG(sptr);
1652     chr = (DTY(ty) == TY_CHAR || DTY(ty) == TY_NCHAR);
1653     islong = chr ? 0 : size_of(ty) == 8;
1654     initd = DINITG(sptr);
1655     idx = MOD_CMN_IDX(acc, chr, islong, initd, THREADG(sptr), dev, con, cpyin,
1656                       link);
1657     if (mod_cmn[idx] == 0)
1658       mod_cmn[idx] =
1659           make_module_common(idx, acc, THREADG(sptr), dev, con, cpyin, link);
1660 
1661     if (SOCPTRG(sptr)) {
1662       /* may have to add 'padding' to the front of this symbol
1663        * if its offset is nonzero; may have to add 'padding' to
1664        * the end of this symbol if its overlap list has any
1665        * variables that extend over the end.
1666        * NOTE that the ADDRESS fields of the equivalenced variables
1667        * are still offsets relative to this symbol and the sptr's
1668        * relative offset from the beginning of its module common
1669        * has not been assigned.
1670        */
1671       ISZ_T offset = ADDRESSG(sptr);
1672       if (offset > 0) {
1673         ISZ_T arraysize = (offset + tysize - 1) / tysize;
1674         int p, pad;
1675         pad = add_padding(sptr, ty, arraysize, idx);
1676         for (p = SOCPTRG(sptr); p; p = SOC_NEXT(p)) {
1677           int overlap = SOC_SPTR(p);
1678           ISZ_T overlap_offset = ADDRESSG(overlap);
1679           if (overlap_offset < offset) {
1680             NEED(soc.avail + 2, soc.base, SOC_ITEM, soc.size, soc.size + 1000);
1681             SOC_SPTR(soc.avail) = pad;
1682             SOC_NEXT(soc.avail) = SOCPTRG(overlap);
1683             SOCPTRP(overlap, soc.avail);
1684             ++soc.avail;
1685             SOC_SPTR(soc.avail) = overlap;
1686             SOC_NEXT(soc.avail) = SOCPTRG(pad);
1687             SOCPTRP(pad, soc.avail);
1688             ++soc.avail;
1689           }
1690         }
1691       }
1692     }
1693     add_to_common(idx, sptr, 0);
1694     if (SOCPTRG(sptr)) {
1695       /* may have to add padding after the variable to account
1696        * for the extra space taken up by the other variables
1697        * equivalenced to this one.
1698        * NOTE that the ADDRESS fields of the equivalenced variables
1699        * are still offsets relative to this symbol and the sptr's
1700        * relative offset from the beginning of its module common
1701        * has been assigned.
1702        */
1703       ISZ_T offset = ADDRESSG(sptr);
1704       ISZ_T sptrsize = size_of(DTYPEG(sptr));
1705       ISZ_T padsize = 0;
1706       int p;
1707       for (p = SOCPTRG(sptr); p; p = SOC_NEXT(p)) {
1708         int overlap = SOC_SPTR(p);
1709         ISZ_T overlap_offset = ADDRESSG(overlap) + offset;
1710         ISZ_T overlap_size = size_of(DTYPEG(overlap));
1711         if (overlap_offset + overlap_size > offset + sptrsize + padsize) {
1712           padsize = overlap_offset + overlap_size - offset - sptrsize;
1713         }
1714         /* add to common block also */
1715         ADDRESSP(overlap, overlap_offset);
1716         add_to_common(idx, overlap, 0);
1717       }
1718       if (padsize > 0) {
1719         int p, pad;
1720         padsize = (padsize + tysize - 1) / tysize;
1721         pad = add_padding(sptr, ty, padsize, idx);
1722         for (p = SOCPTRG(sptr); p; p = SOC_NEXT(p)) {
1723           int overlap = SOC_SPTR(p);
1724           ISZ_T overlap_offset = ADDRESSG(overlap);
1725           ISZ_T overlap_size = size_of(DTYPEG(overlap));
1726           if (overlap_offset + overlap_size > offset + sptrsize) {
1727             int sp;
1728             /* it may already have been added in add_padding */
1729             for (sp = SOCPTRG(overlap); sp; sp = SOC_NEXT(sp)) {
1730               if (SOC_SPTR(sp) == pad)
1731                 break;
1732             }
1733             if (sp == 0) {
1734               NEED(soc.avail + 2, soc.base, SOC_ITEM, soc.size,
1735                    soc.size + 1000);
1736               SOC_SPTR(soc.avail) = pad;
1737               SOC_NEXT(soc.avail) = SOCPTRG(overlap);
1738               SOCPTRP(overlap, soc.avail);
1739               ++soc.avail;
1740               SOC_SPTR(soc.avail) = overlap;
1741               SOC_NEXT(soc.avail) = SOCPTRG(pad);
1742               SOCPTRP(pad, soc.avail);
1743               ++soc.avail;
1744             }
1745           }
1746         }
1747       }
1748     }
1749     break;
1750   }
1751 } /* check_sc */
1752 
1753 static ISZ_T
get_address(int sptr)1754 get_address(int sptr)
1755 {
1756   ISZ_T addr;
1757   if (!EQVG(sptr) || SCOPEG(sptr) == stb.curr_scope)
1758     return ADDRESSG(sptr);
1759   addr = get_address(SCOPEG(sptr));
1760   addr += ADDRESSG(sptr);
1761   ADDRESSP(sptr, addr);
1762   SCOPEP(sptr, stb.curr_scope);
1763   return addr;
1764 } /* get_address */
1765 
1766 static void
fix_module_common(void)1767 fix_module_common(void)
1768 {
1769   int sptr, symavl;
1770   int i;
1771   ITEMX *px;
1772   LOGICAL err;
1773   int evp, firstevp;
1774 
1775   if (gbl.maxsev >= 3) {
1776     gbl.currsub = modu_sym; /* trick semfin & summary */
1777     semfin();               /* to cleanup, free space, etc. */
1778     return;
1779   }
1780 
1781   BZERO(mod_cmn, char, sizeof(mod_cmn));
1782   BZERO(mod_cmn_naln, char, sizeof(mod_cmn_naln));
1783 
1784   for (sptr = stb.firstusym; sptr < stb.stg_avail; sptr++) {
1785     if (IGNOREG(sptr))
1786       continue;
1787     switch (STYPEG(sptr)) {
1788     case ST_PARAM:
1789       if (DTY(DTYPEG(sptr)) == TY_ARRAY) {
1790         /* emit the data inits for the named array constant */
1791         init_named_array_constant(sptr, modu_sym);
1792       }
1793       break;
1794     default:
1795       break;
1796     }
1797   }
1798 
1799   gbl.rutype = RU_SUBR;   /* trick semfin */
1800   gbl.currsub = modu_sym; /* trick semfin */
1801 
1802   semfin();
1803 
1804   mdalloc_list = pointer_list = NULL;
1805   symavl = stb.stg_avail;
1806   for (sptr = stb.firstusym; sptr < symavl; sptr++) {
1807     if (IGNOREG(sptr))
1808       continue;
1809     if (SCOPEG(sptr) != stb.curr_scope)
1810       continue;
1811     if (ENCLFUNCG(sptr) == 0)
1812       ENCLFUNCP(sptr, modu_sym);
1813     if (ENCLFUNCG(sptr) != modu_sym)
1814       continue;
1815     if (NOMDCOMG(sptr))
1816       continue;
1817     switch (STYPEG(sptr)) {
1818     case ST_ARRAY:
1819     case ST_VAR:
1820     case ST_STRUCT:
1821     case ST_UNION:
1822       err = 0;
1823       if (SCG(sptr) != SC_DUMMY) {
1824         int dtype, dty;
1825         dtype = DTYPEG(sptr);
1826         if (DTY(dtype) == TY_ARRAY && ADJARRG(sptr)) {
1827           error(310, 3, gbl.lineno,
1828                 "Automatic arrays are not allowed in a MODULE -",
1829                 SYMNAME(sptr));
1830           err = 1;
1831         }
1832         dty = DTYG(dtype);
1833         if ((dty == TY_CHAR || dty == TY_NCHAR) && ADJLENG(sptr)) {
1834           error(310, 3, gbl.lineno,
1835                 "Adjustable-length character variables are "
1836                 "not allowed in a MODULE -",
1837                 SYMNAME(sptr));
1838           err = 1;
1839         }
1840       }
1841       if (!err)
1842         check_sc(sptr);
1843       break;
1844     case ST_IDENT:
1845       STYPEP(sptr, ST_VAR);
1846       err = 0;
1847       if (SCG(sptr) != SC_DUMMY) {
1848         int dtype, dty;
1849         dtype = DTYPEG(sptr);
1850         dty = DTYG(dtype);
1851         if ((dty == TY_CHAR || dty == TY_NCHAR) && ADJLENG(sptr)) {
1852           error(310, 3, gbl.lineno,
1853                 "Adjustable-length character variables are "
1854                 "not allowed in a MODULE -",
1855                 SYMNAME(sptr));
1856           err = 1;
1857         }
1858       }
1859       if (!err)
1860         check_sc(sptr);
1861       break;
1862     case ST_UNKNOWN: /* ignore */
1863       break;
1864     case ST_NML:
1865       if (mod_cmn[NML_MOD] == 0)
1866         mod_cmn[NML_MOD] = make_module_common(NML_MOD, 0, 0, 0, 0, 0, 0);
1867       add_to_common(NML_MOD, ADDRESSG(sptr), 0);
1868       /* mark as referenced, so it gets declared everywhere */
1869       REFP(sptr, 1);
1870       break;
1871     default:
1872       break;
1873     }
1874   }
1875   /* make sure all overlapped variables are listed in the module common */
1876   for (i = 0; i < N_MOD_CMN; ++i) {
1877     if (mod_cmn[i] <= 0)
1878       continue;
1879     for (sptr = CMEMFG(mod_cmn[i]); sptr != NOSYM; sptr = SYMLKG(sptr)) {
1880       int p;
1881       for (p = SOCPTRG(sptr); p; p = SOC_NEXT(p)) {
1882         int s = SOC_SPTR(p);
1883         if (SCG(s) != SC_CMBLK)
1884           add_to_common(i, s, 0);
1885       }
1886     }
1887   }
1888   /* Get correct addresses in the module common blocks */
1889   /* Store in the SCOPE field a symbol pointer to the symbol to which
1890    * this symbol is equivalenced.  If SCOPEG(sptr)!=module then
1891    * SCOPEG(sptr) is the symbol to which sptr is equivalenced.
1892    * Also, ADDRESSG(sptr) is the byte offset of sptr relative to
1893    * the address of SCOPEG(sptr). */
1894   firstevp = 0;
1895   for (evp = sem.eqvlist; evp; evp = EQV(evp).next) {
1896     if (!HCCSYMG(CMBLKG(EQV(evp).sptr))) {
1897       /* skip user common blocks */
1898       continue;
1899     }
1900     if (EQV(evp).is_first < 0) {
1901       firstevp = 0;
1902     } else if (EQV(evp).is_first > 0) {
1903       firstevp = evp;
1904     } else if (firstevp != 0) {
1905       /* if EQVG(evp->sptr), set address of evp->sptr relative to
1906        * that of firstevp; otherwise, the other way around */
1907       if (EQVG(EQV(evp).sptr)) {
1908         /* see if we've already done this */
1909         if (SCOPEG(EQV(evp).sptr) == stb.curr_scope) {
1910           SCOPEP(EQV(evp).sptr, EQV(firstevp).sptr);
1911           ADDRESSP(EQV(evp).sptr,
1912                    EQV(firstevp).byte_offset - EQV(evp).byte_offset);
1913         }
1914       } else {
1915         if (SCOPEG(EQV(firstevp).sptr) == stb.curr_scope) {
1916           /* EQV(evp).sptr already has an address; set address of
1917            * firstevp relative to that of evp->sptr */
1918           ADDRESSP(EQV(firstevp).sptr, ADDRESSG(EQV(evp).sptr) +
1919                                            EQV(evp).byte_offset -
1920                                            EQV(firstevp).byte_offset);
1921         }
1922       }
1923     }
1924   }
1925   firstevp = 0;
1926   for (evp = sem.eqvlist; evp; evp = EQV(evp).next) {
1927     if (!HCCSYMG(CMBLKG(EQV(evp).sptr))) {
1928       /* skip user common blocks */
1929       continue;
1930     }
1931     if (EQV(evp).is_first < 0) {
1932       firstevp = 0;
1933     } else if (EQV(evp).is_first > 0) {
1934       firstevp = evp;
1935     } else if (firstevp != 0) {
1936       if (EQVG(EQV(evp).sptr) && SCOPEG(EQV(evp).sptr) != stb.curr_scope) {
1937         ISZ_T addr = get_address(SCOPEG(EQV(evp).sptr));
1938         addr += ADDRESSG(EQV(evp).sptr);
1939         ADDRESSP(EQV(evp).sptr, addr);
1940         SCOPEP(EQV(evp).sptr, stb.curr_scope);
1941       }
1942     }
1943   }
1944   for (px = mdalloc_list; px != NULL; px = px->next)
1945     /* for each allocatable variable, create its run-time descriptor
1946      *     "module-name$array-name$al"
1947      */
1948     make_rte_descriptor(px->val, "al");
1949 
1950   for (px = pointer_list; px != NULL; px = px->next)
1951     /* for each pointer variable, create its run-time descriptor
1952      *     "module-name$array-name$ptr"
1953      */
1954     make_rte_descriptor(px->val, "ptr");
1955 
1956   gbl.currsub = modu_sym; /* trick summary */
1957   gbl.rutype = RU_BDATA;  /* write blockdata for module */
1958 }
1959 
1960 LOGICAL
has_cuda_data(void)1961 has_cuda_data(void)
1962 {
1963 #ifdef DEVICEG
1964   int cmblk;
1965   for (cmblk = FIRST_DEV_COMMON; cmblk < LAST_DEV_COMMON; ++cmblk)
1966     if (mod_cmn[cmblk])
1967       return TRUE;
1968   for (cmblk = gbl.cmblks; cmblk > NOSYM; cmblk = SYMLKG(cmblk)) {
1969     if (SCOPEG(cmblk) == gbl.currsub &&
1970         (DEVICEG(cmblk) || CONSTANTG(cmblk) || MANAGEDG(cmblk)))
1971       return TRUE;
1972   }
1973 #endif
1974   return FALSE;
1975 } /* has_cuda_data */
1976 
1977 static void
export_all(void)1978 export_all(void)
1979 {
1980   char *t_nm;
1981   if (module_directory_list == NULL) {
1982     t_nm = getitem(8, strlen(modu_name) + strlen(MOD_SUFFIX) + 1);
1983     strcpy(t_nm, modu_name);
1984   } else {
1985     /* use first name on the module_directory list */
1986     int ml;
1987     ml = strlen(module_directory_list->module_directory);
1988     t_nm = getitem(8, ml + strlen(modu_name) + strlen(MOD_SUFFIX) + 2);
1989     if (ml == 0) {
1990       strcpy(t_nm, modu_name);
1991     } else {
1992       strcpy(t_nm, module_directory_list->module_directory);
1993       if (module_directory_list->module_directory[ml - 1] != '/') {
1994         strcat(t_nm, "/");
1995       }
1996       strcat(t_nm, modu_name);
1997     }
1998   }
1999   convert_2dollar_signs_to_hyphen(t_nm);
2000   strcat(t_nm, MOD_SUFFIX);
2001   outfile = fopen(t_nm, "w+");
2002   if (outfile == NULL) {
2003     error(4, 0, gbl.lineno, "Unable to create MODULE file", t_nm);
2004     return;
2005   }
2006   if (sem.mod_dllexport) {
2007     /*
2008      * The DLL flag of the module will not set if the dllexport only occurs
2009      * within a contained procedure.
2010      */
2011     DLLP(modu_sym, DLL_EXPORT);
2012   }
2013   if (single_outfile_name) {
2014     mod_index *p;
2015     if (single_outfile == NULL) {
2016       single_outfile = fopen(single_outfile_name, "w+");
2017       if (single_outfile == NULL) {
2018         error(4, 0, gbl.lineno, "Unable to create MODULE file",
2019               single_outfile_name);
2020         return;
2021       }
2022     }
2023     if (mod_index_list && strcmp(modu_name, mod_index_list->module_name) == 0) {
2024       fseek(single_outfile, mod_index_list->offset, SEEK_SET);
2025     } else {
2026       p = (mod_index *)getitem(8, sizeof(mod_index));
2027       p->next = mod_index_list;
2028       p->module_name = strcpy(getitem(8, strlen(modu_name) + 1), modu_name);
2029       p->offset = ftell(single_outfile);
2030       mod_index_list = p;
2031     }
2032     export_module(single_outfile, modu_name, modu_sym, 0);
2033   }
2034   export_module(outfile, modu_name, modu_sym, 1);
2035   dbg_dump("export_all", 0x1000);
2036 }
2037 
2038 /*
2039  * close the single-output combined .mod file
2040  * write the combined .mod index file, if we're supposed to
2041  */
2042 void
mod_fini(void)2043 mod_fini(void)
2044 {
2045   if (single_outfile) {
2046     fclose(single_outfile);
2047     if (single_outfile_index_name) {
2048       mod_index *p, *q;
2049       single_outfile = fopen(single_outfile_index_name, "w+");
2050       if (single_outfile == NULL) {
2051         error(4, 0, gbl.lineno, "Unable to create MODULE index file",
2052               single_outfile_index_name);
2053         return;
2054       }
2055       if (mod_index_list) {
2056         /* reverse the list */
2057         p = mod_index_list;
2058         mod_index_list = NULL;
2059         for (; p; p = q) {
2060           q = p->next;
2061           p->next = mod_index_list;
2062           mod_index_list = p;
2063         }
2064         for (p = mod_index_list; p; p = p->next) {
2065           fprintf(single_outfile, "%" GBL_SIZE_T_FORMAT ":%s " LLF "\n",
2066                   strlen(p->module_name), p->module_name, p->offset);
2067         }
2068       }
2069       fprintf(single_outfile, "%d:%s %d\n", 0, "", 0);
2070       fclose(single_outfile);
2071     }
2072     single_outfile = NULL;
2073   } else if (single_outfile_name) {
2074     /* make sure the file is written as an empty file */
2075     single_outfile = fopen(single_outfile_name, "w+");
2076     if (single_outfile)
2077       fclose(single_outfile);
2078     if (single_outfile_index_name) {
2079       single_outfile = fopen(single_outfile_index_name, "w+");
2080       if (single_outfile)
2081         fclose(single_outfile);
2082     }
2083   }
2084 } /* mod_fini */
2085 
2086 #define NO_PTR XBIT(49, 0x8000)
2087 #define NO_CHARPTR XBIT(58, 0x1)
2088 #define NO_DERIVEDPTR XBIT(58, 0x40000)
2089 /*
2090  * A run-time descriptor is created for an object in the form of a common block
2091  * consisting of the object's pointer & offset variables and its static
2092  * descriptor.  The order of the common block members is:
2093  *     variable's pointer variable
2094  *     variable's pointer variable
2095  *     variable's static descriptor
2096  *          ...
2097  * Since this common block is created early, need to ensure that
2098  * the common is not rewritten (i.e., set its SEQ flag).
2099  *
2100  * The name of the common block is derived from the name of the module,
2101  * the name of the object, and the kind of object (module allocatable,
2102  * dynamic, pointer, etc.) which is denoted by 'suffix'.
2103  */
2104 static void
make_rte_descriptor(int obj,char * suffix)2105 make_rte_descriptor(int obj, char *suffix)
2106 {
2107   int acc, idx, islong, initd, dev, con, cpyin, link;
2108   int s;
2109 
2110   if (SDSCG(obj) == 0) {
2111     get_static_descriptor(obj);
2112     get_all_descriptors(obj);
2113   }
2114   SCP(obj, SC_BASED); /* these objects are always pointer-based */
2115 
2116   acc = PRIVATEG(obj);
2117   islong = sizeof(DT_INT) == 8;
2118   initd = 0; /* DINITG(obj); -- POINTER could be init'd => NULL() but aux
2119               * components will be zero, i.e., do not have to explicitly
2120               * initialize.
2121               */
2122 #ifdef DEVICEG
2123   dev = 0;
2124   cpyin = 0;
2125   if (DEVICEG(obj) || MANAGEDG(obj) || ACCCREATEG(obj) || ACCRESIDENTG(obj))
2126     dev = 1;
2127   if (ACCCOPYING(obj))
2128     cpyin = 1;
2129   link = 0;
2130   if (ACCLINKG(obj)) {
2131     dev = 1;
2132     link = 1;
2133   }
2134   /*
2135    * Descriptor for texture pointer is CONSTANT for performance.
2136    * Otherwise need to allow writing by ALLOCATE/DEALLOCATE in device code.
2137    * Unless the xbit is set.  Performance problem reported by Kato, FS#20305
2138    */
2139   if (TEXTUREG(obj) && POINTERG(obj)) {
2140     con = CONSTANTG(obj) || dev;
2141   } else {
2142     if ((MANAGEDG(obj) && !XBIT(137, 0x4000)) || XBIT(137, 0x40))
2143       con = CONSTANTG(obj) || dev;
2144     else
2145       con = CONSTANTG(obj);
2146   }
2147 #else
2148   dev = 0;
2149   con = 0;
2150   cpyin = 0;
2151   link = 0;
2152 #endif
2153   idx = MOD_CMN_IDX(acc, 0, islong, initd, THREADG(obj), dev, con, cpyin, link);
2154   if (mod_cmn[idx] == 0)
2155     mod_cmn[idx] =
2156         make_module_common(idx, acc, THREADG(obj), dev, con, cpyin, link);
2157   s = SDSCG(obj);
2158   add_to_common(idx, s, 1);
2159   PRIVATEP(s, acc);
2160 
2161   s = PTROFFG(obj);
2162   add_to_common(idx, s, 1);
2163   PRIVATEP(s, acc);
2164 
2165   s = MIDNUMG(obj);
2166   add_to_common(idx, s, 1);
2167   PRIVATEP(s, acc);
2168 
2169   if (F77OUTPUT) {
2170     int noptr, dtype, dty, chr;
2171     dtype = DTYPEG(obj);
2172     dty = DTYG(dtype);
2173     noptr = 0;
2174     chr = 0;
2175     if (NO_PTR) {
2176       noptr = 1;
2177     } else if ((dty == TY_NCHAR || dty == TY_CHAR) && NO_CHARPTR) {
2178       noptr = 1;
2179       chr = 1;
2180     } else if (dty == TY_DERIVED && NO_DERIVEDPTR) {
2181       noptr = 1;
2182     }
2183     if (noptr) {
2184       int dev, con, cpyin, link;
2185       islong = sizeof(dty) == 8;
2186 #ifdef DEVICEG
2187       dev = 0;
2188       cpyin = 0;
2189       link = 0;
2190       if (DEVICEG(obj) || MANAGEDG(obj) || ACCCREATEG(obj) || ACCRESIDENTG(obj))
2191         dev = 1;
2192       if (ACCCOPYING(obj))
2193         cpyin = 1;
2194       if (ACCLINKG(obj)) {
2195         dev = 1;
2196         link = 1;
2197       }
2198       con = CONSTANTG(obj);
2199 #else
2200       dev = 0;
2201       con = 0;
2202       cpyin = 0;
2203       link = 0;
2204 #endif
2205       idx = MOD_CMN_IDX(acc, chr, islong, initd, THREADG(obj), dev, con, cpyin,
2206                         link);
2207       if (mod_cmn[idx] == 0)
2208         mod_cmn[idx] =
2209             make_module_common(idx, acc, THREADG(obj), dev, con, cpyin, link);
2210       add_to_common(idx, obj, 0);
2211     }
2212   }
2213 }
2214 
2215 /* return the DTYPEG(sym), except for arrays, return its base type */
2216 static int
basedtype(int sym)2217 basedtype(int sym)
2218 {
2219   int dtype;
2220   dtype = DTYPEG(sym);
2221   if (DTY(dtype) == TY_ARRAY)
2222     dtype = DTY(dtype + 1);
2223   return dtype;
2224 } /* basedtype */
2225 
2226 static void
add_to_common(int cmidx,int mem,int atstart)2227 add_to_common(int cmidx, int mem, int atstart)
2228 {
2229   int cm;
2230   cm = mod_cmn[cmidx];
2231   SCP(mem, SC_CMBLK);
2232   CMBLKP(mem, cm);
2233   if (ENCLFUNCG(mem) == 0) {
2234     ENCLFUNCP(mem, modu_sym);
2235   }
2236   if (atstart) {
2237     if (CMEMLG(cm) <= NOSYM) {
2238       CMEMLP(cm, mem);
2239     } else {
2240       SYMLKP(mem, CMEMFG(cm));
2241     }
2242     CMEMFP(cm, mem);
2243     if (!EQVG(mem)) {
2244       ISZ_T size;
2245       size = SIZEG(cm);
2246       size += size_of_var(mem);
2247       SIZEP(cm, size);
2248     }
2249   } else {
2250     int s, sptr;
2251     ISZ_T maddr, msz;
2252 
2253     for (sptr = CMEMFG(mod_cmn[cmidx]); sptr != NOSYM; sptr = SYMLKG(sptr)) {
2254       if (sptr == mem) {
2255         goto skipmem; /* already process this member */
2256       }
2257     }
2258 
2259     if (CMEMFG(cm) <= NOSYM) {
2260       CMEMFP(cm, mem);
2261     } else {
2262       SYMLKP(CMEMLG(cm), mem);
2263     }
2264     CMEMLP(cm, mem);
2265     SYMLKP(mem, NOSYM);
2266     if (!EQVG(mem)) {
2267       ISZ_T size;
2268       int addr;
2269 #ifdef PDALNG
2270       if (!XBIT(57, 0x1000000) && PDALNG(mem)) {
2271         if (PDALNG(cm) < PDALNG(mem))
2272           PDALNP(cm, PDALNG(mem));
2273       }
2274 #endif
2275       size = SIZEG(cm);
2276       addr = alignment_of_var(mem);
2277       size = ALIGN(size, addr);
2278       ADDRESSP(mem, size);
2279       msz = size_of_var(mem);
2280       msz = pad_cmn_mem(mem, msz, &mod_cmn_naln[cmidx]);
2281       size += msz;
2282       SIZEP(cm, size);
2283     }
2284   skipmem:
2285     /* is there anything else in the common block that should
2286      * be in the SOC list for this member */
2287     maddr = ADDRESSG(mem);
2288     msz = size_of_var(mem);
2289     for (s = CMEMFG(cm); s > NOSYM; s = SYMLKG(s)) {
2290       ISZ_T saddr, ssz;
2291       saddr = ADDRESSG(s);
2292       ssz = size_of_var(s);
2293       /* is there an overlay? mem starting point within s space,
2294        * or s starting point within mem space */
2295       if (s != mem && ((maddr >= saddr && maddr < saddr + ssz) ||
2296                        (saddr >= maddr && saddr < maddr + msz))) {
2297         /* yes, make sure they are in each other's SOC list */
2298         int p;
2299         for (p = SOCPTRG(s); p; p = SOC_NEXT(p)) {
2300           if (SOC_SPTR(p) == mem)
2301             break;
2302         }
2303         if (p == 0) {
2304           /* not found; add mem to SOC(s), s to SOC(mem) */
2305           NEED(soc.avail + 2, soc.base, SOC_ITEM, soc.size, soc.size + 1000);
2306           SOC_SPTR(soc.avail) = mem;
2307           SOC_NEXT(soc.avail) = SOCPTRG(s);
2308           SOCPTRP(s, soc.avail);
2309           ++soc.avail;
2310           SOC_SPTR(soc.avail) = s;
2311           SOC_NEXT(soc.avail) = SOCPTRG(mem);
2312           SOCPTRP(mem, soc.avail);
2313           ++soc.avail;
2314         }
2315       }
2316     }
2317   }
2318   if (DINITG(mem)) {
2319     DINITP(cm, 1);
2320   }
2321 }
2322 
2323 /* ----------------------------------------------------------- */
2324 
2325 void
mod_init()2326 mod_init()
2327 {
2328   init_use_tree();
2329   restore_module_state();
2330   limitsptr = stb.stg_avail;
2331   if (exportb.hmark.maxast >= astb.stg_avail) {
2332     /*
2333      * The max ast read from the module file is greater than the
2334      * the last ast created; allocate asts so that the available
2335      * ast # is 1 larger than the max ast read.
2336      */
2337     int i = exportb.hmark.maxast - astb.stg_avail;
2338     do {
2339       (void)new_node(A_ID);
2340     } while (--i >= 0);
2341   }
2342   sem.mod_public_level = sem.scope_level - 1;
2343   dbg_dump("mod_init", 0x2000);
2344 }
2345 
2346 int
mod_add_subprogram(int subp)2347 mod_add_subprogram(int subp)
2348 {
2349   int new_sb;
2350   int i;
2351   SPTR s;
2352   LOGICAL any_impl;
2353 
2354   /*
2355    * a 'procedure' of the same name as the contained procedure could
2356    * have been created in the module specification part.  One example
2357    * is when the procedure appears in a generic interface, i.e., from
2358    * FS#17246:
2359    *   interface constructor
2360    *     procedure subr
2361    *     !! moduleprocedure subr ! is a work-around
2362    *   end interface
2363    *   ...
2364    *   contains
2365    *     subroutine subr
2366    *   ...
2367    * In this situation, it's better to just represent the procedure
2368    * as an alias of the contained procedure, subp
2369    */
2370   for (new_sb = HASHLKG(subp); new_sb; new_sb = HASHLKG(new_sb)) {
2371     /*
2372      * search the hash list of the contained routine for a  ST_PROC
2373      * in the same scope; if found use it as the alias!
2374      */
2375     if (NMPTRG(new_sb) != NMPTRG(subp))
2376       continue;
2377     if (STYPEG(new_sb) == ST_PROC && SCOPEG(new_sb) == gbl.currmod) {
2378       int swp = subp;
2379       subp = new_sb;
2380       new_sb = swp;
2381       break;
2382     }
2383   }
2384   if (!new_sb) {
2385     /*  ST_PROC of the same name not found  */
2386     new_sb = insert_dup_sym(subp);
2387   }
2388   if (ENCLFUNCG(new_sb) == 0) {
2389     ENCLFUNCP(new_sb, gbl.currmod);
2390   }
2391   STYPEP(subp, ST_ALIAS);
2392   DPDSCP(subp, 0);
2393   PARAMCTP(subp, 0);
2394   FUNCLINEP(subp, 0);
2395   FVALP(subp, 0);
2396   SYMLKP(subp, new_sb);
2397   INMODULEP(new_sb, 1);
2398   if (ISSUBMODULEG(new_sb)) {
2399     for (s = HASHLKG(subp); s; s = HASHLKG(s)) {
2400       if (NMPTRG(s) == NMPTRG(subp) && STYPEG(s) == ST_PROC) {
2401         SCOPEP(subp, SCOPEG(s));
2402       }
2403     }
2404   } else {
2405     SCOPEP(subp, gbl.currmod);
2406   }
2407 
2408   if (sem.mod_dllexport) {
2409     DLLP(subp, DLL_EXPORT);
2410     DLLP(new_sb, DLL_EXPORT);
2411   }
2412   export_append_sym(subp);
2413 
2414   any_impl = FALSE;
2415   for (i = 0; i < impl.avl; i++) {
2416     IMPL *ipl;
2417     ipl = impl.base + i;
2418     ast_implicit(ipl->firstc, ipl->lastc, ipl->dtype);
2419     if (ipl->dtype != 0)
2420       any_impl = TRUE;
2421   }
2422   /*
2423    * if there were any IMPLICITs associated with spec lists, adjust
2424    * the dtypes of function and dummy arguments if necessary.
2425    */
2426   if (any_impl) {
2427     int arg;
2428     int count;
2429 
2430     if (gbl.rutype == RU_FUNC && !DCLDG(subp)) {
2431       setimplicit(subp);
2432       DTYPEP(new_sb, DTYPEG(subp)); /* propogate */
2433     }
2434 
2435     i = DPDSCG(subp);
2436     for (count = PARAMCTG(subp); count > 0; count--) {
2437       arg = aux.dpdsc_base[i];
2438       if (!DCLDG(arg))
2439         setimplicit(arg);
2440       i++;
2441     }
2442   }
2443   if (XBIT(52, 0x80)) {
2444     char linkage_name[2048];
2445     snprintf(linkage_name, sizeof(linkage_name), ".%s.%s", modu_name,
2446              SYMNAME(new_sb));
2447     ALTNAMEP(new_sb, getstring(linkage_name, strlen(linkage_name)));
2448   }
2449   return new_sb;
2450 }
2451 
2452 void
mod_end_subprogram(void)2453 mod_end_subprogram(void)
2454 {
2455   if (sem.mod_cnt == 1) {
2456     export_public_used_modules(sem.mod_public_level);
2457   }
2458 }
2459 
2460 static void
export_public_used_modules(int scopelevel)2461 export_public_used_modules(int scopelevel)
2462 {
2463   if (sem.mod_public_flag && sem.scope_stack) {
2464     SCOPESTACK *scope = get_scope(scopelevel);
2465     for (; scope != 0; scope = next_scope(scope)) {
2466       if (scope->kind == SCOPE_USE && !scope->Private) {
2467         export_public_module(scope->sptr, scope->except);
2468       }
2469     }
2470   }
2471 }
2472 
2473 void
mod_end_subprogram_two(void)2474 mod_end_subprogram_two(void)
2475 {
2476   int i, sptr, dpdsc, arg, link;
2477   ACCL *accessp;
2478 
2479   if (sem.mod_cnt == 1) {
2480     /* go through symbols, see if any should be private */
2481     if (!sem.mod_public_flag) {
2482       for (sptr = limitsptr; sptr < stb.stg_avail; ++sptr) {
2483         switch (STYPEG(sptr)) {
2484         case ST_UNKNOWN:
2485         case ST_NML:
2486         case ST_PROC:
2487         case ST_PARAM:
2488         case ST_TYPEDEF:
2489         case ST_OPERATOR:
2490         case ST_MODPROC:
2491         case ST_CMBLK:
2492         case ST_IDENT:
2493         case ST_VAR:
2494         case ST_ARRAY:
2495         case ST_DESCRIPTOR:
2496         case ST_STRUCT:
2497         case ST_UNION:
2498         case ST_ALIAS:
2499         case ST_ENTRY:
2500           PRIVATEP(sptr, 1);
2501           break;
2502         default:
2503           break;
2504         }
2505       }
2506     }
2507     for (accessp = sem.accl.next; accessp != NULL; accessp = accessp->next) {
2508       sptr = accessp->sptr;
2509       if (sptr >= limitsptr) {
2510         PRIVATEP(sptr, accessp->type == 'v');
2511       }
2512     }
2513     /* see if any should be marked public or private */
2514     for (sptr = stb.firstusym; sptr < stb.stg_avail; ++sptr) {
2515       switch (STYPEG(sptr)) {
2516       case ST_MODPROC:
2517       case ST_ALIAS:
2518         link = SYMLKG(sptr);
2519         if (link) {
2520           if (PRIVATEG(sptr)) {
2521             PRIVATEP(link, 1);
2522           } else {
2523             PRIVATEP(link, 0);
2524           }
2525         }
2526         break;
2527       case ST_PROC:
2528         /* mark the arguments */
2529         for (dpdsc = DPDSCG(sptr), i = PARAMCTG(sptr); i; --i, ++dpdsc) {
2530           arg = aux.dpdsc_base[dpdsc];
2531           PRIVATEP(arg, PRIVATEG(sptr));
2532         }
2533         break;
2534       default:;
2535       }
2536     }
2537     /* set 'DCLD' so it will not be implicitly typed; the leading
2538      * character has been changed by mangling, so implicit typing will fail */
2539     if (gbl.rutype == RU_FUNC) {
2540       if (STYPEG(gbl.currsub) == ST_ALIAS && SYMLKG(gbl.currsub) > NOSYM) {
2541         DCLDP(SYMLKG(gbl.currsub), 1);
2542       } else if (STYPEG(gbl.currsub) == ST_ENTRY) {
2543         DCLDP(gbl.currsub, 1);
2544       }
2545     }
2546 
2547     reset_module_state();
2548   }
2549 }
2550 
rw_mod_state(RW_ROUTINE,RW_FILE)2551 void rw_mod_state(RW_ROUTINE, RW_FILE)
2552 {
2553   int nw;
2554   RW_SCALAR(usedb.avl);
2555   if (usedb.avl) {
2556     if (ISREAD()) {
2557       if (usedb.sz == 0) {
2558         usedb.sz = usedb.avl + 5;
2559         NEW(usedb.base, USED, usedb.sz);
2560         BZERO(usedb.base, USED, usedb.avl);
2561       } else {
2562         NEED(usedb.avl, usedb.base, USED, usedb.sz, usedb.avl + 5);
2563       }
2564     }
2565     RW_FD(usedb.base, USED, usedb.avl);
2566   }
2567 } /* rw_mod_state */
2568 
2569 static void
dbg_dump(const char * name,int dbgbit)2570 dbg_dump(const char *name, int dbgbit)
2571 {
2572 #if DEBUG
2573   if (DBGBIT(4, dbgbit) || DBGBIT(5, dbgbit)) {
2574     fprintf(gbl.dbgfil, ">>>>>> begin %s\n", name);
2575     if (DBGBIT(4, dbgbit))
2576       dump_ast();
2577     if (DBGBIT(5, dbgbit)) {
2578       symdmp(gbl.dbgfil, DBGBIT(5, 8));
2579       dmp_dtype();
2580     }
2581     fprintf(gbl.dbgfil, ">>>>>> end %s\n", name);
2582   }
2583 #endif
2584 }
2585 
2586 #if DEBUG
2587 void
dusedb()2588 dusedb()
2589 {
2590   MODULE_ID id;
2591   fprintf(stderr, "--- usedb: sz=%d\n", usedb.sz);
2592   for (id = FIRST_USER_MODULE; id < usedb.avl; id++) {
2593     USED used = usedb.base[id];
2594     fprintf(stderr, "%d: sym=%d:%s", id, used.module, SYMNAME(used.module));
2595     if (used.unrestricted) fprintf(stderr, " unrestricted");
2596     if (used.submodule) fprintf(stderr, " submodule");
2597     if (used.rename) fprintf(stderr, " rename=%s", used.rename);
2598   }
2599 }
2600 #endif
2601