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