1 /* global.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1997 Free Software Foundation, Inc.
3 Contributed by James Craig Burley (burley@gnu.org).
5 This file is part of GNU Fortran.
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 Manages information kept across individual program units within a single
26 source file. This includes reporting errors when a name is defined
27 multiple times (for example, two program units named FOO) and when a
28 COMMON block is given initial data in more than one program unit.
44 /* Externals defined here. */
47 /* Simple definitions and enumerations. */
50 /* Internal typedefs. */
53 /* Private include files. */
56 /* Internal structure definitions. */
59 /* Static objects accessed by functions in this module. */
62 static ffenameSpace ffeglobal_filewide_ = NULL;
63 static char *ffeglobal_type_string_[] =
65 [FFEGLOBAL_typeNONE] "??",
66 [FFEGLOBAL_typeMAIN] "main program",
67 [FFEGLOBAL_typeEXT] "external",
68 [FFEGLOBAL_typeSUBR] "subroutine",
69 [FFEGLOBAL_typeFUNC] "function",
70 [FFEGLOBAL_typeBDATA] "block data",
71 [FFEGLOBAL_typeCOMMON] "common block",
72 [FFEGLOBAL_typeANY] "?any?"
76 /* Static functions (internal). */
79 /* Internal macros. */
82 /* Call given fn with all globals
84 ffeglobal (*fn)(ffeglobal g);
85 ffeglobal_drive(fn); */
89 ffeglobal_drive (ffeglobal (*fn) ())
91 if (ffeglobal_filewide_ != NULL)
92 ffename_space_drive_global (ffeglobal_filewide_, fn);
96 /* ffeglobal_new_ -- Make new global
100 g = ffeglobal_new_(n); */
102 #if FFEGLOBAL_ENABLED
104 ffeglobal_new_ (ffename n)
110 g = (ffeglobal) malloc_new_ks (malloc_pool_image (), "FFEGLOBAL",
113 #ifdef FFECOM_globalHOOK
114 g->hook = FFECOM_globalNULL;
118 ffename_set_global (n, g);
124 /* ffeglobal_init_1 -- Initialize per file
126 ffeglobal_init_1(); */
131 #if FFEGLOBAL_ENABLED
132 if (ffeglobal_filewide_ != NULL)
133 ffename_space_kill (ffeglobal_filewide_);
134 ffeglobal_filewide_ = ffename_space_new (malloc_pool_image ());
138 /* ffeglobal_init_common -- Initial value specified for common block
140 ffesymbol s; // the ffesymbol for the common block
141 ffelexToken t; // the token with the point of initialization
142 ffeglobal_init_common(s,t);
144 For back ends where file-wide global symbols are not maintained, does
145 nothing. Otherwise, makes sure this common block hasn't already been
146 initialized in a previous program unit, and flag that it's been
147 initialized in this one. */
150 ffeglobal_init_common (ffesymbol s, ffelexToken t)
152 #if FFEGLOBAL_ENABLED
155 g = ffesymbol_global (s);
157 if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON))
159 if (g->type == FFEGLOBAL_typeANY)
162 if (g->tick == ffe_count_2)
167 if (g->u.common.initt != NULL)
169 ffebad_start (FFEBAD_COMMON_ALREADY_INIT);
170 ffebad_string (ffesymbol_text (s));
171 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
172 ffebad_here (1, ffelex_token_where_line (g->u.common.initt),
173 ffelex_token_where_column (g->u.common.initt));
177 /* Complain about just one attempt to reinit per program unit, but
178 continue referring back to the first such successful attempt. */
182 if (g->u.common.blank)
184 ffebad_start (FFEBAD_COMMON_BLANK_INIT);
185 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
189 g->u.common.initt = ffelex_token_use (t);
192 g->tick = ffe_count_2;
196 /* ffeglobal_new_common -- New common block
198 ffesymbol s; // the ffesymbol for the new common block
199 ffelexToken t; // the token with the name of the common block
200 bool blank; // TRUE if blank common
201 ffeglobal_new_common(s,t,blank);
203 For back ends where file-wide global symbols are not maintained, does
204 nothing. Otherwise, makes sure this symbol hasn't been seen before or
205 is known as a common block. */
208 ffeglobal_new_common (ffesymbol s, ffelexToken t, bool blank)
210 #if FFEGLOBAL_ENABLED
214 if (ffesymbol_global (s) == NULL)
216 n = ffename_find (ffeglobal_filewide_, t);
217 g = ffename_global (n);
221 g = ffesymbol_global (s);
225 if ((g != NULL) && (g->type == FFEGLOBAL_typeANY))
228 if ((g != NULL) && (g->type != FFEGLOBAL_typeNONE))
230 if (g->type == FFEGLOBAL_typeCOMMON)
232 assert (g->u.common.blank == blank);
236 if (ffe_is_globals () || ffe_is_warn_globals ())
238 ffebad_start (ffe_is_globals ()
239 ? FFEBAD_FILEWIDE_ALREADY_SEEN
240 : FFEBAD_FILEWIDE_ALREADY_SEEN_W);
241 ffebad_string (ffelex_token_text (t));
242 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
243 ffebad_here (1, ffelex_token_where_line (g->t),
244 ffelex_token_where_column (g->t));
247 g->type = FFEGLOBAL_typeANY;
254 g = ffeglobal_new_ (n);
255 g->intrinsic = FALSE;
257 else if (g->intrinsic
258 && !g->explicit_intrinsic
259 && ffe_is_warn_globals ())
261 ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
262 ffebad_string (ffelex_token_text (t));
263 ffebad_string ("common block");
264 ffebad_string ("intrinsic");
265 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
266 ffebad_here (1, ffelex_token_where_line (g->t),
267 ffelex_token_where_column (g->t));
270 g->t = ffelex_token_use (t);
271 g->type = FFEGLOBAL_typeCOMMON;
272 g->u.common.have_pad = FALSE;
273 g->u.common.have_save = FALSE;
274 g->u.common.have_size = FALSE;
275 g->u.common.blank = blank;
278 ffesymbol_set_global (s, g);
282 /* ffeglobal_new_progunit_ -- New program unit
284 ffesymbol s; // the ffesymbol for the new unit
285 ffelexToken t; // the token with the name of the unit
286 ffeglobalType type; // the type of the new unit
287 ffeglobal_new_progunit_(s,t,type);
289 For back ends where file-wide global symbols are not maintained, does
290 nothing. Otherwise, makes sure this symbol hasn't been seen before. */
293 ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
295 #if FFEGLOBAL_ENABLED
299 n = ffename_find (ffeglobal_filewide_, t);
300 g = ffename_global (n);
301 if ((g != NULL) && (g->type == FFEGLOBAL_typeANY))
305 && ((g->type == FFEGLOBAL_typeMAIN)
306 || (g->type == FFEGLOBAL_typeSUBR)
307 || (g->type == FFEGLOBAL_typeFUNC)
308 || (g->type == FFEGLOBAL_typeBDATA))
309 && g->u.proc.defined)
311 if (ffe_is_globals () || ffe_is_warn_globals ())
313 ffebad_start (ffe_is_globals ()
314 ? FFEBAD_FILEWIDE_ALREADY_SEEN
315 : FFEBAD_FILEWIDE_ALREADY_SEEN_W);
316 ffebad_string (ffelex_token_text (t));
317 ffebad_here (0, ffelex_token_where_line (t),
318 ffelex_token_where_column (t));
319 ffebad_here (1, ffelex_token_where_line (g->t),
320 ffelex_token_where_column (g->t));
323 g->type = FFEGLOBAL_typeANY;
326 && (g->type != FFEGLOBAL_typeNONE)
327 && (g->type != FFEGLOBAL_typeEXT)
328 && (g->type != type))
330 if (ffe_is_globals () || ffe_is_warn_globals ())
332 ffebad_start (ffe_is_globals ()
333 ? FFEBAD_FILEWIDE_DISAGREEMENT
334 : FFEBAD_FILEWIDE_DISAGREEMENT_W);
335 ffebad_string (ffelex_token_text (t));
336 ffebad_string (ffeglobal_type_string_[type]);
337 ffebad_string (ffeglobal_type_string_[g->type]);
338 ffebad_here (0, ffelex_token_where_line (t),
339 ffelex_token_where_column (t));
340 ffebad_here (1, ffelex_token_where_line (g->t),
341 ffelex_token_where_column (g->t));
344 g->type = FFEGLOBAL_typeANY;
350 g = ffeglobal_new_ (n);
351 g->intrinsic = FALSE;
352 g->u.proc.n_args = -1;
353 g->u.proc.other_t = NULL;
355 else if ((ffesymbol_basictype (s) != FFEINFO_basictypeNONE)
356 && ((ffesymbol_basictype (s) != g->u.proc.bt)
357 || (ffesymbol_kindtype (s) != g->u.proc.kt)
358 || ((ffesymbol_size (s) != FFETARGET_charactersizeNONE)
359 && (ffesymbol_size (s) != g->u.proc.sz))))
361 if (ffe_is_globals () || ffe_is_warn_globals ())
363 ffebad_start (ffe_is_globals ()
364 ? FFEBAD_FILEWIDE_TYPE_MISMATCH
365 : FFEBAD_FILEWIDE_TYPE_MISMATCH_W);
366 ffebad_string (ffelex_token_text (t));
367 ffebad_here (0, ffelex_token_where_line (t),
368 ffelex_token_where_column (t));
369 ffebad_here (1, ffelex_token_where_line (g->t),
370 ffelex_token_where_column (g->t));
373 g->type = FFEGLOBAL_typeANY;
377 && !g->explicit_intrinsic
378 && ffe_is_warn_globals ())
380 ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
381 ffebad_string (ffelex_token_text (t));
382 ffebad_string ("global");
383 ffebad_string ("intrinsic");
384 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
385 ffebad_here (1, ffelex_token_where_line (g->t),
386 ffelex_token_where_column (g->t));
389 g->t = ffelex_token_use (t);
391 || (g->u.proc.bt == FFEINFO_basictypeNONE)
392 || (g->u.proc.kt == FFEINFO_kindtypeNONE))
394 g->u.proc.bt = ffesymbol_basictype (s);
395 g->u.proc.kt = ffesymbol_kindtype (s);
396 g->u.proc.sz = ffesymbol_size (s);
398 g->tick = ffe_count_2;
400 && (g->type != type))
401 g->u.proc.n_args = -1;
403 g->u.proc.defined = TRUE;
406 ffesymbol_set_global (s, g);
410 /* ffeglobal_pad_common -- Check initial padding of common area
412 ffesymbol s; // the common area
413 ffetargetAlign pad; // the initial padding
414 ffeglobal_pad_common(s,pad,ffesymbol_where_line(s),
415 ffesymbol_where_column(s));
417 In global-enabled mode, make sure the padding agrees with any existing
418 padding established for the common area, otherwise complain.
419 In global-disabled mode, warn about nonzero padding. */
422 ffeglobal_pad_common (ffesymbol s, ffetargetAlign pad, ffewhereLine wl,
425 #if FFEGLOBAL_ENABLED
428 g = ffesymbol_global (s);
429 if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON))
430 return; /* Let someone else catch this! */
431 if (g->type == FFEGLOBAL_typeANY)
434 if (!g->u.common.have_pad)
436 g->u.common.have_pad = TRUE;
437 g->u.common.pad = pad;
438 g->u.common.pad_where_line = ffewhere_line_use (wl);
439 g->u.common.pad_where_col = ffewhere_column_use (wc);
443 if (g->u.common.pad != pad)
448 sprintf (&padding_1[0], "%" ffetargetAlign_f "u", pad);
449 sprintf (&padding_2[0], "%" ffetargetAlign_f "u", g->u.common.pad);
450 ffebad_start (FFEBAD_COMMON_DIFF_PAD);
451 ffebad_string (ffesymbol_text (s));
452 ffebad_string (padding_1);
453 ffebad_here (0, wl, wc);
454 ffebad_string (padding_2);
455 ffebad_string ((pad == 1)
456 ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS);
457 ffebad_string ((g->u.common.pad == 1)
458 ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS);
459 ffebad_here (1, g->u.common.pad_where_line, g->u.common.pad_where_col);
466 { /* Warn about initial padding in common area. */
469 sprintf (&padding[0], "%" ffetargetAlign_f "u", pad);
470 ffebad_start (FFEBAD_COMMON_INIT_PAD);
471 ffebad_string (ffesymbol_text (s));
472 ffebad_string (padding);
473 ffebad_string ((pad == 1)
474 ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS);
475 ffebad_here (0, wl, wc);
480 /* Collect info for a global's argument. */
483 ffeglobal_proc_def_arg (ffesymbol s, int argno, char *name, ffeglobalArgSummary as,
484 ffeinfoBasictype bt, ffeinfoKindtype kt,
487 ffeglobal g = ffesymbol_global (s);
488 ffeglobalArgInfo_ ai;
492 if (g->type == FFEGLOBAL_typeANY)
495 assert (g->u.proc.n_args >= 0);
497 if (argno >= g->u.proc.n_args)
498 return; /* Already complained about this discrepancy. */
500 ai = &g->u.proc.arg_info[argno];
502 /* Maybe warn about previous references. */
505 && ffe_is_warn_globals ())
513 case FFEGLOBAL_argsummaryREF:
514 if ((ai->as != FFEGLOBAL_argsummaryREF)
515 && (ai->as != FFEGLOBAL_argsummaryNONE)
516 && ((ai->as != FFEGLOBAL_argsummaryDESCR) /* Choose better message. */
517 || (ai->bt != FFEINFO_basictypeCHARACTER)
521 refwhy = "passed by reference";
525 case FFEGLOBAL_argsummaryDESCR:
526 if ((ai->as != FFEGLOBAL_argsummaryDESCR)
527 && (ai->as != FFEGLOBAL_argsummaryNONE)
528 && ((ai->as != FFEGLOBAL_argsummaryREF) /* Choose better message. */
529 || (bt != FFEINFO_basictypeCHARACTER)
533 refwhy = "passed by descriptor";
537 case FFEGLOBAL_argsummaryPROC:
538 if ((ai->as != FFEGLOBAL_argsummaryPROC)
539 && (ai->as != FFEGLOBAL_argsummarySUBR)
540 && (ai->as != FFEGLOBAL_argsummaryFUNC)
541 && (ai->as != FFEGLOBAL_argsummaryNONE))
544 refwhy = "a procedure";
548 case FFEGLOBAL_argsummarySUBR:
549 if ((ai->as != FFEGLOBAL_argsummaryPROC)
550 && (ai->as != FFEGLOBAL_argsummarySUBR)
551 && (ai->as != FFEGLOBAL_argsummaryNONE))
554 refwhy = "a subroutine";
558 case FFEGLOBAL_argsummaryFUNC:
559 if ((ai->as != FFEGLOBAL_argsummaryPROC)
560 && (ai->as != FFEGLOBAL_argsummaryFUNC)
561 && (ai->as != FFEGLOBAL_argsummaryNONE))
564 refwhy = "a function";
568 case FFEGLOBAL_argsummaryALTRTN:
569 if ((ai->as != FFEGLOBAL_argsummaryALTRTN)
570 && (ai->as != FFEGLOBAL_argsummaryNONE))
573 refwhy = "an alternate-return label";
581 if ((refwhy != NULL) && (defwhy == NULL))
583 /* Fill in the def info. */
587 case FFEGLOBAL_argsummaryNONE:
591 case FFEGLOBAL_argsummaryVAL:
592 defwhy = "passed by value";
595 case FFEGLOBAL_argsummaryREF:
596 defwhy = "passed by reference";
599 case FFEGLOBAL_argsummaryDESCR:
600 defwhy = "passed by descriptor";
603 case FFEGLOBAL_argsummaryPROC:
604 defwhy = "a procedure";
607 case FFEGLOBAL_argsummarySUBR:
608 defwhy = "a subroutine";
611 case FFEGLOBAL_argsummaryFUNC:
612 defwhy = "a function";
615 case FFEGLOBAL_argsummaryALTRTN:
616 defwhy = "an alternate-return label";
620 case FFEGLOBAL_argsummaryPTR:
621 defwhy = "a pointer";
632 && (bt != FFEINFO_basictypeHOLLERITH)
633 && (bt != FFEINFO_basictypeTYPELESS)
634 && (bt != FFEINFO_basictypeNONE)
635 && (ai->bt != FFEINFO_basictypeHOLLERITH)
636 && (ai->bt != FFEINFO_basictypeTYPELESS)
637 && (ai->bt != FFEINFO_basictypeNONE))
642 && ((bt != FFEINFO_basictypeREAL)
643 || (ai->bt != FFEINFO_basictypeCOMPLEX))
644 && ((bt != FFEINFO_basictypeCOMPLEX)
645 || (ai->bt != FFEINFO_basictypeREAL)))
647 warn = TRUE; /* We can cope with these differences. */
649 defwhy = "some other type";
652 if (!warn && (kt != ai->kt))
655 refwhy = "one precision";
656 defwhy = "some other precision";
665 sprintf (&num[0], "%d", argno + 1);
668 if (strlen (name) < 30)
669 sprintf (&num[0], "%d (named `%s')", argno + 1, name);
671 sprintf (&num[0], "%d (named `%.*s...')", argno + 1, 30, name);
673 ffebad_start (FFEBAD_FILEWIDE_ARG_W);
674 ffebad_string (ffesymbol_text (s));
676 ffebad_string (refwhy);
677 ffebad_string (defwhy);
678 ffebad_here (0, ffelex_token_where_line (g->t), ffelex_token_where_column (g->t));
679 ffebad_here (1, ffelex_token_where_line (ai->t), ffelex_token_where_column (ai->t));
684 /* Define this argument. */
687 ffelex_token_kill (ai->t);
688 if ((as != FFEGLOBAL_argsummaryPROC)
690 ai->as = as; /* Otherwise leave SUBR/FUNC info intact. */
691 ai->t = ffelex_token_use (g->t);
696 ai->name = malloc_new_ks (malloc_pool_image (),
697 "ffeglobalArgInfo_ name",
699 strcpy (ai->name, name);
706 /* Collect info on #args a global accepts. */
709 ffeglobal_proc_def_nargs (ffesymbol s, int n_args)
711 ffeglobal g = ffesymbol_global (s);
715 if (g->type == FFEGLOBAL_typeANY)
718 if (g->u.proc.n_args >= 0)
720 if (g->u.proc.n_args == n_args)
723 if (ffe_is_warn_globals ())
725 ffebad_start (FFEBAD_FILEWIDE_NARGS_W);
726 ffebad_string (ffesymbol_text (s));
727 if (g->u.proc.n_args > n_args)
728 ffebad_string ("few");
730 ffebad_string ("many");
731 ffebad_here (0, ffelex_token_where_line (g->u.proc.other_t),
732 ffelex_token_where_column (g->u.proc.other_t));
733 ffebad_here (1, ffelex_token_where_line (g->t),
734 ffelex_token_where_column (g->t));
739 /* This is new info we can use in cross-checking future references
740 and a possible future definition. */
742 g->u.proc.n_args = n_args;
743 g->u.proc.other_t = NULL; /* No other reference yet. */
747 g->u.proc.arg_info = NULL;
752 = (ffeglobalArgInfo_) malloc_new_ks (malloc_pool_image (),
754 n_args * sizeof (g->u.proc.arg_info[0]));
756 g->u.proc.arg_info[n_args].t = NULL;
759 /* Verify that the info for a global's argument is valid. */
762 ffeglobal_proc_ref_arg (ffesymbol s, int argno, ffeglobalArgSummary as,
763 ffeinfoBasictype bt, ffeinfoKindtype kt,
764 bool array, ffelexToken t)
766 ffeglobal g = ffesymbol_global (s);
767 ffeglobalArgInfo_ ai;
771 if (g->type == FFEGLOBAL_typeANY)
774 assert (g->u.proc.n_args >= 0);
776 if (argno >= g->u.proc.n_args)
777 return TRUE; /* Already complained about this discrepancy. */
779 ai = &g->u.proc.arg_info[argno];
781 /* Warn about previous references. */
792 case FFEGLOBAL_argsummaryNONE:
793 if (g->u.proc.defined)
797 defwhy = "not optional";
801 case FFEGLOBAL_argsummaryVAL:
802 if (ai->as != FFEGLOBAL_argsummaryVAL)
805 refwhy = "passed by value";
809 case FFEGLOBAL_argsummaryREF:
810 if ((ai->as != FFEGLOBAL_argsummaryREF)
811 && (ai->as != FFEGLOBAL_argsummaryNONE)
812 && ((ai->as != FFEGLOBAL_argsummaryDESCR) /* Choose better message. */
813 || (ai->bt != FFEINFO_basictypeCHARACTER)
817 refwhy = "passed by reference";
821 case FFEGLOBAL_argsummaryDESCR:
822 if ((ai->as != FFEGLOBAL_argsummaryDESCR)
823 && (ai->as != FFEGLOBAL_argsummaryNONE)
824 && ((ai->as != FFEGLOBAL_argsummaryREF) /* Choose better message. */
825 || (bt != FFEINFO_basictypeCHARACTER)
829 refwhy = "passed by descriptor";
833 case FFEGLOBAL_argsummaryPROC:
834 if ((ai->as != FFEGLOBAL_argsummaryPROC)
835 && (ai->as != FFEGLOBAL_argsummarySUBR)
836 && (ai->as != FFEGLOBAL_argsummaryFUNC)
837 && (ai->as != FFEGLOBAL_argsummaryNONE))
840 refwhy = "a procedure";
844 case FFEGLOBAL_argsummarySUBR:
845 if ((ai->as != FFEGLOBAL_argsummaryPROC)
846 && (ai->as != FFEGLOBAL_argsummarySUBR)
847 && (ai->as != FFEGLOBAL_argsummaryNONE))
850 refwhy = "a subroutine";
854 case FFEGLOBAL_argsummaryFUNC:
855 if ((ai->as != FFEGLOBAL_argsummaryPROC)
856 && (ai->as != FFEGLOBAL_argsummaryFUNC)
857 && (ai->as != FFEGLOBAL_argsummaryNONE))
860 refwhy = "a function";
864 case FFEGLOBAL_argsummaryALTRTN:
865 if ((ai->as != FFEGLOBAL_argsummaryALTRTN)
866 && (ai->as != FFEGLOBAL_argsummaryNONE))
869 refwhy = "an alternate-return label";
874 case FFEGLOBAL_argsummaryPTR:
875 if ((ai->as != FFEGLOBAL_argsummaryPTR)
876 && (ai->as != FFEGLOBAL_argsummaryNONE))
879 refwhy = "a pointer";
888 if ((refwhy != NULL) && (defwhy == NULL))
890 /* Fill in the def info. */
894 case FFEGLOBAL_argsummaryNONE:
898 case FFEGLOBAL_argsummaryVAL:
899 defwhy = "passed by value";
902 case FFEGLOBAL_argsummaryREF:
903 defwhy = "passed by reference";
906 case FFEGLOBAL_argsummaryDESCR:
907 defwhy = "passed by descriptor";
910 case FFEGLOBAL_argsummaryPROC:
911 defwhy = "a procedure";
914 case FFEGLOBAL_argsummarySUBR:
915 defwhy = "a subroutine";
918 case FFEGLOBAL_argsummaryFUNC:
919 defwhy = "a function";
922 case FFEGLOBAL_argsummaryALTRTN:
923 defwhy = "an alternate-return label";
927 case FFEGLOBAL_argsummaryPTR:
928 defwhy = "a pointer";
939 && (bt != FFEINFO_basictypeHOLLERITH)
940 && (bt != FFEINFO_basictypeTYPELESS)
941 && (bt != FFEINFO_basictypeNONE)
942 && (ai->bt != FFEINFO_basictypeHOLLERITH)
943 && (ai->bt != FFEINFO_basictypeNONE)
944 && (ai->bt != FFEINFO_basictypeTYPELESS))
949 && ((bt != FFEINFO_basictypeREAL)
950 || (ai->bt != FFEINFO_basictypeCOMPLEX))
951 && ((bt != FFEINFO_basictypeCOMPLEX)
952 || (ai->bt != FFEINFO_basictypeREAL)))
954 if (((bt == FFEINFO_basictypeINTEGER)
955 && (ai->bt == FFEINFO_basictypeLOGICAL))
956 || ((bt == FFEINFO_basictypeLOGICAL)
957 && (ai->bt == FFEINFO_basictypeINTEGER)))
958 warn = TRUE; /* We can cope with these differences. */
962 defwhy = "some other type";
965 if (!fail && !warn && (kt != ai->kt))
968 refwhy = "one precision";
969 defwhy = "some other precision";
973 if (fail && ! g->u.proc.defined)
975 /* No point failing if we're worried only about invocations. */
980 if (fail && ! ffe_is_globals ())
986 if (fail || (warn && ffe_is_warn_globals ()))
990 if (ai->name == NULL)
991 sprintf (&num[0], "%d", argno + 1);
994 if (strlen (ai->name) < 30)
995 sprintf (&num[0], "%d (named `%s')", argno + 1, ai->name);
997 sprintf (&num[0], "%d (named `%.*s...')", argno + 1, 30, ai->name);
999 ffebad_start (fail ? FFEBAD_FILEWIDE_ARG : FFEBAD_FILEWIDE_ARG_W);
1000 ffebad_string (ffesymbol_text (s));
1001 ffebad_string (num);
1002 ffebad_string (refwhy);
1003 ffebad_string (defwhy);
1004 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1005 ffebad_here (1, ffelex_token_where_line (ai->t), ffelex_token_where_column (ai->t));
1007 return (fail ? FALSE : TRUE);
1014 /* Define this argument. */
1017 ffelex_token_kill (ai->t);
1018 if ((as != FFEGLOBAL_argsummaryPROC)
1021 ai->t = ffelex_token_use (g->t);
1030 ffeglobal_proc_ref_nargs (ffesymbol s, int n_args, ffelexToken t)
1032 ffeglobal g = ffesymbol_global (s);
1036 if (g->type == FFEGLOBAL_typeANY)
1039 if (g->u.proc.n_args >= 0)
1041 if (g->u.proc.n_args == n_args)
1044 if (g->u.proc.defined && ffe_is_globals ())
1046 ffebad_start (FFEBAD_FILEWIDE_NARGS);
1047 ffebad_string (ffesymbol_text (s));
1048 if (g->u.proc.n_args > n_args)
1049 ffebad_string ("few");
1051 ffebad_string ("many");
1052 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1053 ffebad_here (1, ffelex_token_where_line (g->t),
1054 ffelex_token_where_column (g->t));
1059 if (ffe_is_warn_globals ())
1061 ffebad_start (FFEBAD_FILEWIDE_NARGS_W);
1062 ffebad_string (ffesymbol_text (s));
1063 if (g->u.proc.n_args > n_args)
1064 ffebad_string ("few");
1066 ffebad_string ("many");
1067 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1068 ffebad_here (1, ffelex_token_where_line (g->t),
1069 ffelex_token_where_column (g->t));
1073 return TRUE; /* Don't replace the info we already have. */
1076 /* This is new info we can use in cross-checking future references
1077 and a possible future definition. */
1079 g->u.proc.n_args = n_args;
1080 g->u.proc.other_t = ffelex_token_use (t);
1082 /* Make this "the" place we found the global, since it has the most info. */
1085 ffelex_token_kill (g->t);
1086 g->t = ffelex_token_use (t);
1090 g->u.proc.arg_info = NULL;
1095 = (ffeglobalArgInfo_) malloc_new_ks (malloc_pool_image (),
1096 "ffeglobalArgInfo_",
1097 n_args * sizeof (g->u.proc.arg_info[0]));
1098 while (n_args-- > 0)
1099 g->u.proc.arg_info[n_args].t = NULL;
1104 /* Return a global for a promoted symbol (one that has heretofore
1105 been assumed to be local, but since discovered to be global). */
1108 ffeglobal_promoted (ffesymbol s)
1110 #if FFEGLOBAL_ENABLED
1114 assert (ffesymbol_global (s) == NULL);
1116 n = ffename_find (ffeglobal_filewide_, ffename_token (ffesymbol_name (s)));
1117 g = ffename_global (n);
1125 /* Register a reference to an intrinsic. Such a reference is always
1126 valid, though a warning might be in order if the same name has
1127 already been used for a global. */
1130 ffeglobal_ref_intrinsic (ffesymbol s, ffelexToken t, bool explicit)
1132 #if FFEGLOBAL_ENABLED
1136 if (ffesymbol_global (s) == NULL)
1138 n = ffename_find (ffeglobal_filewide_, t);
1139 g = ffename_global (n);
1143 g = ffesymbol_global (s);
1147 if ((g != NULL) && (g->type == FFEGLOBAL_typeANY))
1150 if ((g != NULL) && (g->type != FFEGLOBAL_typeNONE))
1154 && ffe_is_warn_globals ())
1156 ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
1157 ffebad_string (ffelex_token_text (t));
1158 ffebad_string ("intrinsic");
1159 ffebad_string ("global");
1160 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1161 ffebad_here (1, ffelex_token_where_line (g->t),
1162 ffelex_token_where_column (g->t));
1170 g = ffeglobal_new_ (n);
1171 g->tick = ffe_count_2;
1172 g->type = FFEGLOBAL_typeNONE;
1173 g->intrinsic = TRUE;
1174 g->explicit_intrinsic = explicit;
1175 g->t = ffelex_token_use (t);
1177 else if (g->intrinsic
1178 && (explicit != g->explicit_intrinsic)
1179 && (g->tick != ffe_count_2)
1180 && ffe_is_warn_globals ())
1182 ffebad_start (FFEBAD_INTRINSIC_EXPIMP);
1183 ffebad_string (ffelex_token_text (t));
1184 ffebad_string (explicit ? "explicit" : "implicit");
1185 ffebad_string (explicit ? "implicit" : "explicit");
1186 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1187 ffebad_here (1, ffelex_token_where_line (g->t),
1188 ffelex_token_where_column (g->t));
1193 g->intrinsic = TRUE;
1195 g->explicit_intrinsic = TRUE;
1197 ffesymbol_set_global (s, g);
1201 /* Register a reference to a global. Returns TRUE if the reference
1205 ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
1207 #if FFEGLOBAL_ENABLED
1211 /* It is never really _known_ that an EXTERNAL statement
1212 names a BLOCK DATA by just looking at the program unit,
1213 so override a different notion here. */
1214 if (type == FFEGLOBAL_typeBDATA)
1215 type = FFEGLOBAL_typeEXT;
1217 g = ffesymbol_global (s);
1220 n = ffename_find (ffeglobal_filewide_, t);
1221 g = ffename_global (n);
1223 ffesymbol_set_global (s, g);
1226 if ((g != NULL) && (g->type == FFEGLOBAL_typeANY))
1230 && (g->type != FFEGLOBAL_typeNONE)
1231 && (g->type != type)
1232 && (g->type != FFEGLOBAL_typeEXT)
1233 && (type != FFEGLOBAL_typeEXT))
1235 if ((((type == FFEGLOBAL_typeBDATA)
1236 && (g->type != FFEGLOBAL_typeCOMMON))
1237 || ((g->type == FFEGLOBAL_typeBDATA)
1238 && (type != FFEGLOBAL_typeCOMMON)
1239 && ! g->u.proc.defined)))
1241 #if 0 /* This is likely to just annoy people. */
1242 if (ffe_is_warn_globals ())
1244 ffebad_start (FFEBAD_FILEWIDE_TIFF);
1245 ffebad_string (ffelex_token_text (t));
1246 ffebad_string (ffeglobal_type_string_[type]);
1247 ffebad_string (ffeglobal_type_string_[g->type]);
1248 ffebad_here (0, ffelex_token_where_line (t),
1249 ffelex_token_where_column (t));
1250 ffebad_here (1, ffelex_token_where_line (g->t),
1251 ffelex_token_where_column (g->t));
1256 else if (ffe_is_globals ())
1258 ffebad_start (FFEBAD_FILEWIDE_DISAGREEMENT);
1259 ffebad_string (ffelex_token_text (t));
1260 ffebad_string (ffeglobal_type_string_[type]);
1261 ffebad_string (ffeglobal_type_string_[g->type]);
1262 ffebad_here (0, ffelex_token_where_line (t),
1263 ffelex_token_where_column (t));
1264 ffebad_here (1, ffelex_token_where_line (g->t),
1265 ffelex_token_where_column (g->t));
1267 g->type = FFEGLOBAL_typeANY;
1270 else if (ffe_is_warn_globals ())
1272 ffebad_start (FFEBAD_FILEWIDE_DISAGREEMENT_W);
1273 ffebad_string (ffelex_token_text (t));
1274 ffebad_string (ffeglobal_type_string_[type]);
1275 ffebad_string (ffeglobal_type_string_[g->type]);
1276 ffebad_here (0, ffelex_token_where_line (t),
1277 ffelex_token_where_column (t));
1278 ffebad_here (1, ffelex_token_where_line (g->t),
1279 ffelex_token_where_column (g->t));
1281 g->type = FFEGLOBAL_typeANY;
1287 && (type == FFEGLOBAL_typeFUNC))
1289 /* If just filling in this function's type, do so. */
1290 if ((g->tick == ffe_count_2)
1291 && (ffesymbol_basictype (s) != FFEINFO_basictypeNONE)
1292 && (ffesymbol_kindtype (s) != FFEINFO_kindtypeNONE))
1294 g->u.proc.bt = ffesymbol_basictype (s);
1295 g->u.proc.kt = ffesymbol_kindtype (s);
1296 g->u.proc.sz = ffesymbol_size (s);
1298 /* Else, make sure there is type agreement. */
1299 else if ((g->u.proc.bt != FFEINFO_basictypeNONE)
1300 && (ffesymbol_basictype (s) != FFEINFO_basictypeNONE)
1301 && ((ffesymbol_basictype (s) != g->u.proc.bt)
1302 || (ffesymbol_kindtype (s) != g->u.proc.kt)
1303 || ((ffesymbol_size (s) != g->u.proc.sz)
1304 && g->u.proc.defined
1305 && (g->u.proc.sz != FFETARGET_charactersizeNONE))))
1307 if (ffe_is_globals ())
1309 ffebad_start (FFEBAD_FILEWIDE_TYPE_MISMATCH);
1310 ffebad_string (ffelex_token_text (t));
1311 ffebad_here (0, ffelex_token_where_line (t),
1312 ffelex_token_where_column (t));
1313 ffebad_here (1, ffelex_token_where_line (g->t),
1314 ffelex_token_where_column (g->t));
1316 g->type = FFEGLOBAL_typeANY;
1319 if (ffe_is_warn_globals ())
1321 ffebad_start (FFEBAD_FILEWIDE_TYPE_MISMATCH_W);
1322 ffebad_string (ffelex_token_text (t));
1323 ffebad_here (0, ffelex_token_where_line (t),
1324 ffelex_token_where_column (t));
1325 ffebad_here (1, ffelex_token_where_line (g->t),
1326 ffelex_token_where_column (g->t));
1329 g->type = FFEGLOBAL_typeANY;
1336 g = ffeglobal_new_ (n);
1337 g->t = ffelex_token_use (t);
1338 g->tick = ffe_count_2;
1339 g->intrinsic = FALSE;
1341 g->u.proc.defined = FALSE;
1342 g->u.proc.bt = ffesymbol_basictype (s);
1343 g->u.proc.kt = ffesymbol_kindtype (s);
1344 g->u.proc.sz = ffesymbol_size (s);
1345 g->u.proc.n_args = -1;
1346 ffesymbol_set_global (s, g);
1348 else if (g->intrinsic
1349 && !g->explicit_intrinsic
1350 && (g->tick != ffe_count_2)
1351 && ffe_is_warn_globals ())
1353 ffebad_start (FFEBAD_INTRINSIC_GLOBAL);
1354 ffebad_string (ffelex_token_text (t));
1355 ffebad_string ("global");
1356 ffebad_string ("intrinsic");
1357 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1358 ffebad_here (1, ffelex_token_where_line (g->t),
1359 ffelex_token_where_column (g->t));
1363 if ((g->type != type)
1364 && (type != FFEGLOBAL_typeEXT))
1366 /* We've learned more, so point to where we learned it. */
1367 g->t = ffelex_token_use (t);
1369 #ifdef FFECOM_globalHOOK
1370 g->hook = FFECOM_globalNULL; /* Discard previous _DECL. */
1372 g->u.proc.n_args = -1;
1379 /* ffeglobal_save_common -- Check SAVE status of common area
1381 ffesymbol s; // the common area
1382 bool save; // TRUE if SAVEd, FALSE otherwise
1383 ffeglobal_save_common(s,save,ffesymbol_where_line(s),
1384 ffesymbol_where_column(s));
1386 In global-enabled mode, make sure the save info agrees with any existing
1387 info established for the common area, otherwise complain.
1388 In global-disabled mode, do nothing. */
1391 ffeglobal_save_common (ffesymbol s, bool save, ffewhereLine wl,
1394 #if FFEGLOBAL_ENABLED
1397 g = ffesymbol_global (s);
1398 if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON))
1399 return; /* Let someone else catch this! */
1400 if (g->type == FFEGLOBAL_typeANY)
1403 if (!g->u.common.have_save)
1405 g->u.common.have_save = TRUE;
1406 g->u.common.save = save;
1407 g->u.common.save_where_line = ffewhere_line_use (wl);
1408 g->u.common.save_where_col = ffewhere_column_use (wc);
1412 if ((g->u.common.save != save) && ffe_is_pedantic ())
1414 ffebad_start (FFEBAD_COMMON_DIFF_SAVE);
1415 ffebad_string (ffesymbol_text (s));
1416 ffebad_here (save ? 0 : 1, wl, wc);
1417 ffebad_here (save ? 1 : 0, g->u.common.pad_where_line, g->u.common.pad_where_col);
1424 /* ffeglobal_size_common -- Establish size of COMMON area
1426 ffesymbol s; // the common area
1427 long size; // size in units
1428 if (ffeglobal_size_common(s,size)) // new size is largest seen
1430 In global-enabled mode, set the size if it current size isn't known or is
1431 smaller than new size, and for non-blank common, complain if old size
1432 is different from new. Return TRUE if the new size is the largest seen
1433 for this COMMON area (or if no size was known for it previously).
1434 In global-disabled mode, do nothing. */
1436 #if FFEGLOBAL_ENABLED
1438 ffeglobal_size_common (ffesymbol s, long size)
1442 g = ffesymbol_global (s);
1443 if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON))
1445 if (g->type == FFEGLOBAL_typeANY)
1448 if (!g->u.common.have_size)
1450 g->u.common.have_size = TRUE;
1451 g->u.common.size = size;
1455 if ((g->u.common.size < size) && (g->tick > 0) && (g->tick < ffe_count_2))
1460 sprintf (&oldsize[0], "%ld", g->u.common.size);
1461 sprintf (&newsize[0], "%ld", size);
1463 ffebad_start (FFEBAD_COMMON_ENLARGED);
1464 ffebad_string (ffesymbol_text (s));
1465 ffebad_string (oldsize);
1466 ffebad_string (newsize);
1467 ffebad_string ((g->u.common.size == 1)
1468 ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS);
1469 ffebad_string ((size == 1)
1470 ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS);
1471 ffebad_here (0, ffelex_token_where_line (g->u.common.initt),
1472 ffelex_token_where_column (g->u.common.initt));
1473 ffebad_here (1, ffesymbol_where_line (s),
1474 ffesymbol_where_column (s));
1477 else if ((g->u.common.size != size) && !g->u.common.blank)
1482 /* Warn about this even if not -pedantic, because putting all
1483 program units in a single source file is the only way to
1484 detect this. Apparently UNIX-model linkers neither handle
1485 nor report when they make a common unit smaller than
1486 requested, such as when the smaller-declared version is
1487 initialized and the larger-declared version is not. So
1488 if people complain about strange overwriting, we can tell
1489 them to put all their code in a single file and compile
1490 that way. Warnings about differing sizes must therefore
1491 always be issued. */
1493 sprintf (&oldsize[0], "%ld", g->u.common.size);
1494 sprintf (&newsize[0], "%ld", size);
1496 ffebad_start (FFEBAD_COMMON_DIFF_SIZE);
1497 ffebad_string (ffesymbol_text (s));
1498 ffebad_string (oldsize);
1499 ffebad_string (newsize);
1500 ffebad_string ((g->u.common.size == 1)
1501 ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS);
1502 ffebad_string ((size == 1)
1503 ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS);
1504 ffebad_here (0, ffelex_token_where_line (g->t),
1505 ffelex_token_where_column (g->t));
1506 ffebad_here (1, ffesymbol_where_line (s),
1507 ffesymbol_where_column (s));
1511 if (size > g->u.common.size)
1513 g->u.common.size = size;
1521 ffeglobal_terminate_1 ()