1 /* Implementation of Fortran symbol manager
2 Copyright (C) 1995, 1996, 1997, 2003
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
40 /* Choice of how to handle global symbols -- either global only within the
41 program unit being defined or global within the entire source file.
42 The former is appropriate for systems where an object file can
43 easily be taken apart program unit by program unit, the latter is the
44 UNIX/C model where the object file is essentially a monolith. */
46 #define FFESYMBOL_globalPROGUNIT_ 1
47 #define FFESYMBOL_globalFILE_ 2
49 /* Choose how to handle global symbols here. */
51 /* Would be good to understand why PROGUNIT in this case too.
53 #define FFESYMBOL_globalCURRENT_ FFESYMBOL_globalPROGUNIT_
55 /* Choose how to handle memory pools based on global symbol stuff. */
57 #if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
58 #define FFESYMBOL_SPACE_POOL_ ffe_pool_program_unit()
59 #elif FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_
60 #define FFESYMBOL_SPACE_POOL_ ffe_pool_file()
65 /* What kind of retraction is needed for a symbol? */
67 enum _ffesymbol_retractcommand_
69 FFESYMBOL_retractcommandDELETE_
,
70 FFESYMBOL_retractcommandRETRACT_
,
71 FFESYMBOL_retractcommand_
73 typedef enum _ffesymbol_retractcommand_ ffesymbolRetractCommand_
;
75 /* This object keeps track of retraction for a symbol and links to the next
78 typedef struct _ffesymbol_retract_
*ffesymbolRetract_
;
79 struct _ffesymbol_retract_
81 ffesymbolRetract_ next
;
82 ffesymbolRetractCommand_ command
;
83 ffesymbol live
; /* Live symbol. */
84 ffesymbol symbol
; /* Backup copy of symbol. */
87 static ffebad
ffesymbol_check_token_ (ffelexToken t
, char *c
);
88 static void ffesymbol_kill_manifest_ (void);
89 static ffesymbol
ffesymbol_new_ (ffename n
);
90 static ffesymbol
ffesymbol_unhook_ (ffesymbol s
);
91 static void ffesymbol_whine_state_ (ffebad bad
, ffelexToken t
, char c
);
93 /* Manifest names for unnamed things (as tokens) so we make them only
96 static ffelexToken ffesymbol_token_blank_common_
= NULL
;
97 static ffelexToken ffesymbol_token_unnamed_main_
= NULL
;
98 static ffelexToken ffesymbol_token_unnamed_blockdata_
= NULL
;
100 /* Name spaces currently in force. */
102 static ffenameSpace ffesymbol_global_
= NULL
;
103 static ffenameSpace ffesymbol_local_
= NULL
;
104 static ffenameSpace ffesymbol_sfunc_
= NULL
;
106 /* Keep track of retraction. */
108 static bool ffesymbol_retractable_
= FALSE
;
109 static mallocPool ffesymbol_retract_pool_
;
110 static ffesymbolRetract_ ffesymbol_retract_first_
;
111 static ffesymbolRetract_
*ffesymbol_retract_list_
;
113 /* List of state names. */
115 static const char *const ffesymbol_state_name_
[] =
123 /* List of attribute names. */
125 static const char *const ffesymbol_attr_name_
[] =
127 #define DEFATTR(ATTR,ATTRS,NAME) NAME,
128 #include "symbol.def"
133 /* Check whether the token text has any invalid characters. If not,
134 return FALSE. If so, if error messages inhibited, return TRUE
135 so caller knows to try again later, else report error and return
139 ffesymbol_check_token_ (ffelexToken t
, char *c
)
141 char *p
= ffelex_token_text (t
);
142 ffeTokenLength len
= ffelex_token_length (t
);
144 ffeTokenLength i
= 0;
145 ffebad skip_me
= ((ffe_case_symbol () == FFE_caseINITCAP
)
146 ? FFEBAD_SYMBOL_NOLOWER_INITCAP
: FFEBAD
+ 1);
147 ffebad stop_me
= ((ffe_case_symbol () == FFE_caseINITCAP
)
148 ? FFEBAD
: FFEBAD
+ 1);
152 bad
= ffesrc_bad_char_symbol_init (*p
);
155 for (++i
, ++p
; i
< len
; ++i
, ++p
)
157 bad
= ffesrc_bad_char_symbol_noninit (*p
);
159 continue; /* Keep looking for good InitCap character. */
161 break; /* Found good InitCap character. */
163 break; /* Bad character found. */
170 *c
= *(ffelex_token_text (t
));
178 /* Kill manifest (g77-picked) names. */
181 ffesymbol_kill_manifest_ ()
183 if (ffesymbol_token_blank_common_
!= NULL
)
184 ffelex_token_kill (ffesymbol_token_blank_common_
);
185 if (ffesymbol_token_unnamed_main_
!= NULL
)
186 ffelex_token_kill (ffesymbol_token_unnamed_main_
);
187 if (ffesymbol_token_unnamed_blockdata_
!= NULL
)
188 ffelex_token_kill (ffesymbol_token_unnamed_blockdata_
);
190 ffesymbol_token_blank_common_
= NULL
;
191 ffesymbol_token_unnamed_main_
= NULL
;
192 ffesymbol_token_unnamed_blockdata_
= NULL
;
197 If the "retractable" flag is not set, just return the new symbol.
198 Else, add symbol to the "retract" list as a delete item, set
199 the "have_old" flag, and return the new symbol. */
202 ffesymbol_new_ (ffename n
)
209 s
= (ffesymbol
) malloc_new_ks (FFESYMBOL_SPACE_POOL_
, "FFESYMBOL",
212 s
->other_space_name
= NULL
;
213 #if FFEGLOBAL_ENABLED
216 s
->attrs
= FFESYMBOL_attrsetNONE
;
217 s
->state
= FFESYMBOL_stateNONE
;
218 s
->info
= ffeinfo_new_null ();
222 s
->array_size
= NULL
;
226 s
->dummy_args
= NULL
;
228 s
->common_list
= NULL
;
229 s
->sfunc_expr
= NULL
;
230 s
->list_bottom
= NULL
;
234 s
->hook
= FFECOM_symbolNULL
;
235 s
->sfa_dummy_parent
= NULL
;
236 s
->func_result
= NULL
;
238 s
->check_state
= FFESYMBOL_checkstateNONE_
;
239 s
->check_token
= NULL
;
240 s
->max_entry_num
= 0;
242 s
->generic
= FFEINTRIN_genNONE
;
243 s
->specific
= FFEINTRIN_specNONE
;
244 s
->implementation
= FFEINTRIN_impNONE
;
249 s
->explicit_where
= FALSE
;
250 s
->namelisted
= FALSE
;
253 ffename_set_symbol (n
, s
);
255 if (!ffesymbol_retractable_
)
261 r
= (ffesymbolRetract_
) malloc_new_kp (ffesymbol_retract_pool_
,
262 "FFESYMBOL retract", sizeof (*r
));
264 r
->command
= FFESYMBOL_retractcommandDELETE_
;
266 r
->symbol
= NULL
; /* No backup copy. */
268 *ffesymbol_retract_list_
= r
;
269 ffesymbol_retract_list_
= &r
->next
;
275 /* Unhook a symbol from its (soon-to-be-killed) name obj.
277 NULLify the names to which this symbol points. Do other cleanup as
281 ffesymbol_unhook_ (ffesymbol s
)
283 s
->other_space_name
= s
->name
= NULL
;
284 if ((ffesymbol_attrs (s
) & FFESYMBOL_attrsCBLOCK
)
285 || (ffesymbol_kind (s
) == FFEINFO_kindNAMELIST
))
286 ffebld_end_list (ffesymbol_ptr_to_listbottom (s
));
287 if (s
->check_state
== FFESYMBOL_checkstatePENDING_
)
288 ffelex_token_kill (s
->check_token
);
293 /* Issue diagnostic about bad character in token representing user-defined
297 ffesymbol_whine_state_ (ffebad bad
, ffelexToken t
, char c
)
305 ffebad_here (0, ffelex_token_where_line (t
),
306 ffelex_token_where_column (t
));
307 ffebad_string (badstr
);
311 /* Returns a string representing the attributes set. */
314 ffesymbol_attrs_string (ffesymbolAttrs attrs
)
316 static char string
[FFESYMBOL_attr
* 12 + 20];
322 if (attrs
== FFESYMBOL_attrsetNONE
)
328 for (attr
= 0; attr
< FFESYMBOL_attr
; ++attr
)
330 if (attrs
& ((ffesymbolAttrs
) 1 << attr
))
332 attrs
&= ~((ffesymbolAttrs
) 1 << attr
);
333 strcpy (p
, ffesymbol_attr_name_
[attr
]);
339 if (attrs
== FFESYMBOL_attrsetNONE
)
342 sprintf (p
, "?0x%" ffesymbolAttrs_f
"x?", attrs
);
343 assert (((size_t) (p
- &string
[0])) < ARRAY_SIZE (string
));
347 /* Check symbol's name for validity, considering that it might actually
348 be an intrinsic and thus should not be complained about just yet. */
351 ffesymbol_check (ffesymbol s
, ffelexToken t
, bool maybe_intrin
)
359 if (!ffesrc_check_symbol ()
360 || ((s
->check_state
!= FFESYMBOL_checkstateNONE_
)
361 && ((s
->check_state
!= FFESYMBOL_checkstateINHIBITED_
)
362 || ffebad_inhibit ())))
365 bad
= ffesymbol_check_token_ (t
, &c
);
369 s
->check_state
= FFESYMBOL_checkstateCHECKED_
;
374 && ffeintrin_is_intrinsic (ffelex_token_text (t
), NULL
, FALSE
,
377 s
->check_state
= FFESYMBOL_checkstatePENDING_
;
378 s
->check_token
= ffelex_token_use (t
);
382 if (ffebad_inhibit ())
384 s
->check_state
= FFESYMBOL_checkstateINHIBITED_
;
385 return; /* Don't complain now, do it later. */
388 s
->check_state
= FFESYMBOL_checkstateCHECKED_
;
390 ffesymbol_whine_state_ (bad
, t
, c
);
393 /* Declare a BLOCKDATA unit.
395 Retrieves or creates the ffesymbol for the specified BLOCKDATA (unnamed
396 if t is NULL). Doesn't actually ensure the named item is a
397 BLOCKDATA; the caller must handle that. */
400 ffesymbol_declare_blockdataunit (ffelexToken t
, ffewhereLine wl
,
405 bool user
= (t
!= NULL
);
407 assert (!ffesymbol_retractable_
);
411 if (ffesymbol_token_unnamed_blockdata_
== NULL
)
412 ffesymbol_token_unnamed_blockdata_
413 = ffelex_token_new_name (FFETARGET_nameUNNAMED_BLOCK_DATA
, wl
, wc
);
414 t
= ffesymbol_token_unnamed_blockdata_
;
417 n
= ffename_lookup (ffesymbol_local_
, t
);
419 return ffename_symbol (n
); /* This will become an error. */
421 n
= ffename_find (ffesymbol_global_
, t
);
422 s
= ffename_symbol (n
);
426 ffesymbol_check (s
, t
, FALSE
);
430 s
= ffesymbol_new_ (n
);
432 ffesymbol_check (s
, t
, FALSE
);
434 /* A program unit name also is in the local name space. */
436 n
= ffename_find (ffesymbol_local_
, t
);
437 ffename_set_symbol (n
, s
);
438 s
->other_space_name
= n
;
440 ffeglobal_new_blockdata (s
, t
); /* Detect conflicts, when
446 /* Declare a common block (named or unnamed).
448 Retrieves or creates the ffesymbol for the specified common block (blank
449 common if t is NULL). Doesn't actually ensure the named item is a
450 common block; the caller must handle that. */
453 ffesymbol_declare_cblock (ffelexToken t
, ffewhereLine wl
, ffewhereColumn wc
)
459 assert (!ffesymbol_retractable_
);
464 if (ffesymbol_token_blank_common_
== NULL
)
465 ffesymbol_token_blank_common_
466 = ffelex_token_new_name (FFETARGET_nameBLANK_COMMON
, wl
, wc
);
467 t
= ffesymbol_token_blank_common_
;
472 n
= ffename_find (ffesymbol_global_
, t
);
473 s
= ffename_symbol (n
);
477 ffesymbol_check (s
, t
, FALSE
);
481 s
= ffesymbol_new_ (n
);
483 ffesymbol_check (s
, t
, FALSE
);
485 ffeglobal_new_common (s
, t
, blank
); /* Detect conflicts. */
490 /* Declare a FUNCTION program unit (with distinct RESULT() name).
492 Retrieves or creates the ffesymbol for the specified function. Doesn't
493 actually ensure the named item is a function; the caller must handle
496 If FUNCTION with RESULT() is specified but the names are the same,
497 pretend as though RESULT() was not specified, and don't call this
498 function; use ffesymbol_declare_funcunit() instead. */
501 ffesymbol_declare_funcnotresunit (ffelexToken t
)
507 assert (!ffesymbol_retractable_
);
509 n
= ffename_lookup (ffesymbol_local_
, t
);
511 return ffename_symbol (n
); /* This will become an error. */
513 n
= ffename_find (ffesymbol_global_
, t
);
514 s
= ffename_symbol (n
);
517 ffesymbol_check (s
, t
, FALSE
);
521 s
= ffesymbol_new_ (n
);
522 ffesymbol_check (s
, t
, FALSE
);
524 /* A FUNCTION program unit name also is in the local name space; handle it
525 here since RESULT() is a different name and is handled separately. */
527 n
= ffename_find (ffesymbol_local_
, t
);
528 ffename_set_symbol (n
, s
);
529 s
->other_space_name
= n
;
531 ffeglobal_new_function (s
, t
);/* Detect conflicts, when appropriate. */
536 /* Declare a function result.
538 Retrieves or creates the ffesymbol for the specified function result,
539 whether specified via a distinct RESULT() or by default in a FUNCTION or
543 ffesymbol_declare_funcresult (ffelexToken t
)
549 assert (!ffesymbol_retractable_
);
551 n
= ffename_find (ffesymbol_local_
, t
);
552 s
= ffename_symbol (n
);
556 return ffesymbol_new_ (n
);
559 /* Declare a FUNCTION program unit with no RESULT().
561 Retrieves or creates the ffesymbol for the specified function. Doesn't
562 actually ensure the named item is a function; the caller must handle
565 This is the function to call when the FUNCTION or ENTRY statement has
566 no separate and distinct name specified via RESULT(). That's because
567 this function enters the global name of the function in only the global
568 name space. ffesymbol_declare_funcresult() must still be called to
569 declare the name for the function result in the local name space. */
572 ffesymbol_declare_funcunit (ffelexToken t
)
578 assert (!ffesymbol_retractable_
);
580 n
= ffename_find (ffesymbol_global_
, t
);
581 s
= ffename_symbol (n
);
584 ffesymbol_check (s
, t
, FALSE
);
588 s
= ffesymbol_new_ (n
);
589 ffesymbol_check (s
, t
, FALSE
);
591 ffeglobal_new_function (s
, t
);/* Detect conflicts. */
596 /* Declare a local entity.
598 Retrieves or creates the ffesymbol for the specified local entity.
599 Set maybe_intrin TRUE if this name might turn out to name an
600 intrinsic (legitimately); otherwise if the name doesn't meet the
601 requirements for a user-defined symbol name, a diagnostic will be
602 issued right away rather than waiting until the intrinsicness of the
603 symbol is determined. */
606 ffesymbol_declare_local (ffelexToken t
, bool maybe_intrin
)
613 /* If we're parsing within a statement function definition, return the
614 symbol if already known (a dummy argument for the statement function).
615 Otherwise continue on, which means the symbol is declared within the
616 containing (local) program unit rather than the statement function
619 if ((ffesymbol_sfunc_
!= NULL
)
620 && ((n
= ffename_lookup (ffesymbol_sfunc_
, t
)) != NULL
))
621 return ffename_symbol (n
);
623 n
= ffename_find (ffesymbol_local_
, t
);
624 s
= ffename_symbol (n
);
627 ffesymbol_check (s
, t
, maybe_intrin
);
631 s
= ffesymbol_new_ (n
);
632 ffesymbol_check (s
, t
, maybe_intrin
);
636 /* Declare a main program unit.
638 Retrieves or creates the ffesymbol for the specified main program unit
639 (unnamed main program unit if t is NULL). Doesn't actually ensure the
640 named item is a program; the caller must handle that. */
643 ffesymbol_declare_programunit (ffelexToken t
, ffewhereLine wl
,
648 bool user
= (t
!= NULL
);
650 assert (!ffesymbol_retractable_
);
654 if (ffesymbol_token_unnamed_main_
== NULL
)
655 ffesymbol_token_unnamed_main_
656 = ffelex_token_new_name (FFETARGET_nameUNNAMED_MAIN
, wl
, wc
);
657 t
= ffesymbol_token_unnamed_main_
;
660 n
= ffename_lookup (ffesymbol_local_
, t
);
662 return ffename_symbol (n
); /* This will become an error. */
664 n
= ffename_find (ffesymbol_global_
, t
);
665 s
= ffename_symbol (n
);
669 ffesymbol_check (s
, t
, FALSE
);
673 s
= ffesymbol_new_ (n
);
675 ffesymbol_check (s
, t
, FALSE
);
677 /* A program unit name also is in the local name space. */
679 n
= ffename_find (ffesymbol_local_
, t
);
680 ffename_set_symbol (n
, s
);
681 s
->other_space_name
= n
;
683 ffeglobal_new_program (s
, t
); /* Detect conflicts. */
688 /* Declare a statement-function dummy.
690 Retrieves or creates the ffesymbol for the specified statement
691 function dummy. Also ensures that it has a link to the parent (local)
692 ffesymbol with the same name, creating it if necessary. */
695 ffesymbol_declare_sfdummy (ffelexToken t
)
699 ffesymbol sp
; /* Parent symbol in local area. */
703 n
= ffename_find (ffesymbol_local_
, t
);
704 sp
= ffename_symbol (n
);
706 sp
= ffesymbol_new_ (n
);
707 ffesymbol_check (sp
, t
, FALSE
);
709 n
= ffename_find (ffesymbol_sfunc_
, t
);
710 s
= ffename_symbol (n
);
713 s
= ffesymbol_new_ (n
);
714 s
->sfa_dummy_parent
= sp
;
717 assert (s
->sfa_dummy_parent
== sp
);
722 /* Declare a subroutine program unit.
724 Retrieves or creates the ffesymbol for the specified subroutine
725 Doesn't actually ensure the named item is a subroutine; the caller must
729 ffesymbol_declare_subrunit (ffelexToken t
)
734 assert (!ffesymbol_retractable_
);
737 n
= ffename_lookup (ffesymbol_local_
, t
);
739 return ffename_symbol (n
); /* This will become an error. */
741 n
= ffename_find (ffesymbol_global_
, t
);
742 s
= ffename_symbol (n
);
745 ffesymbol_check (s
, t
, FALSE
);
749 s
= ffesymbol_new_ (n
);
750 ffesymbol_check (s
, t
, FALSE
);
752 /* A program unit name also is in the local name space. */
754 n
= ffename_find (ffesymbol_local_
, t
);
755 ffename_set_symbol (n
, s
);
756 s
->other_space_name
= n
;
758 ffeglobal_new_subroutine (s
, t
); /* Detect conflicts, when
764 /* Call given fn with all local/global symbols.
766 ffesymbol (*fn) (ffesymbol s);
767 ffesymbol_drive (fn); */
770 ffesymbol_drive (ffesymbol (*fn
) (ffesymbol
))
772 assert (ffesymbol_sfunc_
== NULL
); /* Might be ok, but not for current
774 ffename_space_drive_symbol (ffesymbol_local_
, fn
);
775 ffename_space_drive_symbol (ffesymbol_global_
, fn
);
778 /* Call given fn with all sfunc-only symbols.
780 ffesymbol (*fn) (ffesymbol s);
781 ffesymbol_drive_sfnames (fn); */
784 ffesymbol_drive_sfnames (ffesymbol (*fn
) (ffesymbol
))
786 ffename_space_drive_symbol (ffesymbol_sfunc_
, fn
);
789 /* Produce generic error message about a symbol.
791 For now, just output error message using symbol's name and pointing to
795 ffesymbol_error (ffesymbol s
, ffelexToken t
)
798 && ffest_ffebad_start (FFEBAD_SYMERR
))
800 ffebad_string (ffesymbol_text (s
));
801 ffebad_here (0, ffelex_token_where_line (t
),
802 ffelex_token_where_column (t
));
803 ffebad_here (1, ffesymbol_where_line (s
), ffesymbol_where_column (s
));
807 if (ffesymbol_attr (s
, FFESYMBOL_attrANY
))
810 ffesymbol_signal_change (s
); /* May need to back up to previous version. */
811 if ((ffesymbol_attrs (s
) & FFESYMBOL_attrsCBLOCK
)
812 || (ffesymbol_kind (s
) == FFEINFO_kindNAMELIST
))
813 ffebld_end_list (ffesymbol_ptr_to_listbottom (s
));
814 ffesymbol_set_attr (s
, FFESYMBOL_attrANY
);
815 ffesymbol_set_info (s
, ffeinfo_new_any ());
816 ffesymbol_set_state (s
, FFESYMBOL_stateUNDERSTOOD
);
817 if (s
->check_state
== FFESYMBOL_checkstatePENDING_
)
818 ffelex_token_kill (s
->check_token
);
819 s
->check_state
= FFESYMBOL_checkstateCHECKED_
;
820 s
= ffecom_sym_learned (s
);
821 ffesymbol_signal_unreported (s
);
827 ffesymbolAttrs attrs
= FFESYMBOL_attrsetNONE
;
829 assert (FFESYMBOL_state
== ARRAY_SIZE (ffesymbol_state_name_
));
830 assert (FFESYMBOL_attr
== ARRAY_SIZE (ffesymbol_attr_name_
));
831 assert (attrs
== FFESYMBOL_attrsetNONE
);
832 attrs
= ((ffesymbolAttrs
) 1 << FFESYMBOL_attr
);
839 #if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_
840 ffesymbol_global_
= ffename_space_new (ffe_pool_file ());
852 #if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
853 ffesymbol_global_
= ffename_space_new (ffe_pool_program_unit ());
855 ffesymbol_local_
= ffename_space_new (ffe_pool_program_unit ());
861 ffesymbol_sfunc_
= ffename_space_new (ffe_pool_program_unit ());
864 /* Look up a local entity.
866 Retrieves the ffesymbol for the specified local entity, or returns NULL
867 if no local entity by that name exists. */
870 ffesymbol_lookup_local (ffelexToken t
)
877 n
= ffename_lookup (ffesymbol_local_
, t
);
881 s
= ffename_symbol (n
);
882 return s
; /* May be NULL here, too. */
885 /* Registers the symbol as one that is referenced by the
886 current program unit. Currently applies only to
887 symbols known to have global interest (globals and
890 s is the (global/intrinsic) symbol referenced; t is the
891 referencing token; explicit is TRUE if the reference
892 is, e.g., INTRINSIC FOO. */
895 ffesymbol_reference (ffesymbol s
, ffelexToken t
, bool explicit)
903 if (ffesymbol_retractable_
)
907 t
= ffename_token (s
->name
); /* Use the first reference in this program unit. */
909 kind
= ffesymbol_kind (s
);
910 where
= ffesymbol_where (s
);
912 if (where
== FFEINFO_whereINTRINSIC
)
914 ffeglobal_ref_intrinsic (s
, t
,
917 || ffeintrin_is_standard (s
->generic
, s
->specific
));
921 if ((where
!= FFEINFO_whereGLOBAL
)
922 && ((where
!= FFEINFO_whereLOCAL
)
923 || ((kind
!= FFEINFO_kindFUNCTION
)
924 && (kind
!= FFEINFO_kindSUBROUTINE
))))
927 gn
= ffename_lookup (ffesymbol_global_
, t
);
929 gs
= ffename_symbol (gn
);
930 if ((gs
!= NULL
) && (gs
!= s
))
932 /* We have just discovered another global symbol with the same name
933 but a different `nature'. Complain. Note that COMMON /FOO/ can
934 coexist with local symbol FOO, e.g. local variable, just not with
935 CALL FOO, hence the separate namespaces. */
937 ffesymbol_error (gs
, t
);
938 ffesymbol_error (s
, NULL
);
944 case FFEINFO_kindBLOCKDATA
:
945 okay
= ffeglobal_ref_blockdata (s
, t
);
948 case FFEINFO_kindSUBROUTINE
:
949 okay
= ffeglobal_ref_subroutine (s
, t
);
952 case FFEINFO_kindFUNCTION
:
953 okay
= ffeglobal_ref_function (s
, t
);
956 case FFEINFO_kindNONE
:
957 okay
= ffeglobal_ref_external (s
, t
);
961 assert ("bad kind in global ref" == NULL
);
966 ffesymbol_error (s
, NULL
);
969 /* Resolve symbol that has become known intrinsic or non-intrinsic. */
972 ffesymbol_resolve_intrin (ffesymbol s
)
977 if (!ffesrc_check_symbol ())
979 if (s
->check_state
!= FFESYMBOL_checkstatePENDING_
)
981 if (ffebad_inhibit ())
982 return; /* We'll get back to this later. */
984 if (ffesymbol_where (s
) != FFEINFO_whereINTRINSIC
)
986 bad
= ffesymbol_check_token_ (s
->check_token
, &c
);
987 assert (bad
!= FFEBAD
); /* How did this suddenly become ok? */
988 ffesymbol_whine_state_ (bad
, s
->check_token
, c
);
991 s
->check_state
= FFESYMBOL_checkstateCHECKED_
;
992 ffelex_token_kill (s
->check_token
);
995 /* Retract or cancel retract list. */
998 ffesymbol_retract (bool retract
)
1000 ffesymbolRetract_ r
;
1002 ffename other_space_name
;
1006 assert (ffesymbol_retractable_
);
1008 ffesymbol_retractable_
= FALSE
;
1010 for (r
= ffesymbol_retract_first_
; r
!= NULL
; r
= r
->next
)
1016 case FFESYMBOL_retractcommandDELETE_
:
1019 ffecom_sym_retract (ls
);
1021 other_space_name
= ls
->other_space_name
;
1022 ffesymbol_unhook_ (ls
);
1023 malloc_kill_ks (FFESYMBOL_SPACE_POOL_
, ls
, sizeof (*ls
));
1025 ffename_set_symbol (name
, NULL
);
1026 if (other_space_name
!= NULL
)
1027 ffename_set_symbol (other_space_name
, NULL
);
1031 ffecom_sym_commit (ls
);
1032 ls
->have_old
= FALSE
;
1036 case FFESYMBOL_retractcommandRETRACT_
:
1039 ffecom_sym_retract (ls
);
1040 ffesymbol_unhook_ (ls
);
1042 malloc_kill_ks (FFESYMBOL_SPACE_POOL_
, os
, sizeof (*os
));
1046 ffecom_sym_commit (ls
);
1047 ffesymbol_unhook_ (os
);
1048 malloc_kill_ks (FFESYMBOL_SPACE_POOL_
, os
, sizeof (*os
));
1049 ls
->have_old
= FALSE
;
1054 assert ("bad command" == NULL
);
1060 /* Return retractable flag. */
1063 ffesymbol_retractable ()
1065 return ffesymbol_retractable_
;
1068 /* Set retractable flag, retract pool.
1070 Between this call and ffesymbol_retract, any changes made to existing
1071 symbols cause the previous versions of those symbols to be saved, and any
1072 newly created symbols to have their previous nonexistence saved. When
1073 ffesymbol_retract is called, this information either is used to retract
1074 the changes and new symbols, or is discarded. */
1077 ffesymbol_set_retractable (mallocPool pool
)
1079 assert (!ffesymbol_retractable_
);
1081 ffesymbol_retractable_
= TRUE
;
1082 ffesymbol_retract_pool_
= pool
;
1083 ffesymbol_retract_list_
= &ffesymbol_retract_first_
;
1084 ffesymbol_retract_first_
= NULL
;
1087 /* Existing symbol about to be changed; save?
1089 Call this function before changing a symbol if it is possible that
1090 the current actions may need to be undone (i.e. one of several possible
1091 statement forms are being used to analyze the current system).
1093 If the "retractable" flag is not set, just return.
1094 Else, if the symbol's "have_old" flag is set, just return.
1095 Else, make a copy of the symbol and add it to the "retract" list, set
1096 the "have_old" flag, and return. */
1099 ffesymbol_signal_change (ffesymbol s
)
1101 ffesymbolRetract_ r
;
1104 if (!ffesymbol_retractable_
|| s
->have_old
)
1107 r
= (ffesymbolRetract_
) malloc_new_kp (ffesymbol_retract_pool_
,
1108 "FFESYMBOL retract", sizeof (*r
));
1110 r
->command
= FFESYMBOL_retractcommandRETRACT_
;
1112 r
->symbol
= sym
= (ffesymbol
) malloc_new_ks (FFESYMBOL_SPACE_POOL_
,
1113 "FFESYMBOL", sizeof (*sym
));
1114 *sym
= *s
; /* Make an exact copy of the symbol in case
1116 sym
->info
= ffeinfo_use (s
->info
);
1117 if (s
->check_state
== FFESYMBOL_checkstatePENDING_
)
1118 sym
->check_token
= ffelex_token_use (s
->check_token
);
1120 *ffesymbol_retract_list_
= r
;
1121 ffesymbol_retract_list_
= &r
->next
;
1126 /* Returns the string based on the state. */
1129 ffesymbol_state_string (ffesymbolState state
)
1131 if (state
>= ARRAY_SIZE (ffesymbol_state_name_
))
1133 return ffesymbol_state_name_
[state
];
1137 ffesymbol_terminate_0 ()
1142 ffesymbol_terminate_1 ()
1144 #if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_
1145 ffename_space_drive_symbol (ffesymbol_global_
, ffesymbol_unhook_
);
1146 ffename_space_kill (ffesymbol_global_
);
1147 ffesymbol_global_
= NULL
;
1149 ffesymbol_kill_manifest_ ();
1154 ffesymbol_terminate_2 ()
1156 #if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
1157 ffesymbol_kill_manifest_ ();
1162 ffesymbol_terminate_3 ()
1164 #if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
1165 ffename_space_drive_symbol (ffesymbol_global_
, ffesymbol_unhook_
);
1166 ffename_space_kill (ffesymbol_global_
);
1168 ffename_space_drive_symbol (ffesymbol_local_
, ffesymbol_unhook_
);
1169 ffename_space_kill (ffesymbol_local_
);
1170 #if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
1171 ffesymbol_global_
= NULL
;
1173 ffesymbol_local_
= NULL
;
1177 ffesymbol_terminate_4 ()
1179 ffename_space_drive_symbol (ffesymbol_sfunc_
, ffesymbol_unhook_
);
1180 ffename_space_kill (ffesymbol_sfunc_
);
1181 ffesymbol_sfunc_
= NULL
;
1184 /* Update INIT info to TRUE and all equiv/storage too.
1186 If INIT flag is TRUE, does nothing. Else sets it to TRUE and calls
1187 on the ffeequiv and ffestorag modules to update their INIT flags if
1188 the <s> symbol has those objects, and also updates the common area if
1192 ffesymbol_update_init (ffesymbol s
)
1201 if ((s
->equiv
!= NULL
)
1202 && !ffeequiv_is_init (s
->equiv
))
1203 ffeequiv_update_init (s
->equiv
);
1205 if ((s
->storage
!= NULL
)
1206 && !ffestorag_is_init (s
->storage
))
1207 ffestorag_update_init (s
->storage
);
1209 if ((s
->common
!= NULL
)
1210 && (!ffesymbol_is_init (s
->common
)))
1211 ffesymbol_update_init (s
->common
);
1213 for (item
= s
->common_list
; item
!= NULL
; item
= ffebld_trail (item
))
1215 if (!ffesymbol_is_init (ffebld_symter (ffebld_head (item
))))
1216 ffesymbol_update_init (ffebld_symter (ffebld_head (item
)));
1220 /* Update SAVE info to TRUE and all equiv/storage too.
1222 If SAVE flag is TRUE, does nothing. Else sets it to TRUE and calls
1223 on the ffeequiv and ffestorag modules to update their SAVE flags if
1224 the <s> symbol has those objects, and also updates the common area if
1228 ffesymbol_update_save (ffesymbol s
)
1237 if ((s
->equiv
!= NULL
)
1238 && !ffeequiv_is_save (s
->equiv
))
1239 ffeequiv_update_save (s
->equiv
);
1241 if ((s
->storage
!= NULL
)
1242 && !ffestorag_is_save (s
->storage
))
1243 ffestorag_update_save (s
->storage
);
1245 if ((s
->common
!= NULL
)
1246 && (!ffesymbol_is_save (s
->common
)))
1247 ffesymbol_update_save (s
->common
);
1249 for (item
= s
->common_list
; item
!= NULL
; item
= ffebld_trail (item
))
1251 if (!ffesymbol_is_save (ffebld_symter (ffebld_head (item
))))
1252 ffesymbol_update_save (ffebld_symter (ffebld_head (item
)));