2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 # include "splintMacros.nf"
31 # include "exprChecks.h"
32 # include "filelocStack.h"
37 # include "cgrammar.h"
39 # include "mtgrammar.h"
51 CX_FUNCTION
, CX_FCNDECLARATION
,
52 CX_MACROFCN
, CX_MACROCONST
, CX_UNKNOWNMACRO
,
53 CX_ITERDEF
, CX_ITEREND
,
54 CX_OLDSTYLESCOPE
, /* Parsing old-style parameter declarations */
55 CX_LCL
, CX_LCLLIB
, CX_MT
61 int speclinesprocessed
;
63 flagMarkerList markers
;
66 ** used to record state where a macro must match a function name
67 ** (i.e., no params were listed in the macro definition
70 bool macroMissingParams BOOLBITS
;
71 bool preprocessing BOOLBITS
;
72 bool incommandline BOOLBITS
;
73 bool insuppressregion BOOLBITS
;
74 bool inDerivedFile BOOLBITS
;
75 bool instandardlib BOOLBITS
;
76 bool inimport BOOLBITS
;
77 bool inheader BOOLBITS
;
78 bool inmacrocache BOOLBITS
;
79 bool protectVars BOOLBITS
;
81 bool showfunction BOOLBITS
;
82 bool savedFlags BOOLBITS
;
83 bool justpopped BOOLBITS
;
84 bool anyExports BOOLBITS
;
85 bool inFunctionHeader BOOLBITS
;
99 filelocStack locstack
;
102 /*@observer@*/ sRef aliasAnnote
;
103 /*@observer@*/ sRef aliasAnnoteAls
;
107 /*@observer@*/ sRefSet mods
;
109 /* file access types */
112 /* local access types (this function) */
115 /* no access types (@noaccess) */
118 /*@observer@*/ globSet globs
;
119 /*@only@*/ globSet globs_used
;
123 /*@reldef@*/ maccesst
*moduleaccess
; /* Not defined is nmods == 0. */
129 bool flags
[NUMFLAGS
];
130 bool saveflags
[NUMFLAGS
];
131 bool setGlobally
[NUMFLAGS
];
132 bool setLocally
[NUMFLAGS
];
134 int values
[NUMVALUEFLAGS
];
135 int counters
[NUMVALUEFLAGS
];
137 o_cstring strings
[NUMSTRINGFLAGS
];
138 sRefSetList modrecs
; /* Keep track of file static symbols modified. */
140 metaStateTable stateTable
; /* User-defined state information. */
141 annotationTable annotTable
; /* User-defined annotations table. */
146 /*@dependent@*/ /*@exposed@*/ uentry fcn
;
150 union u_cont savecont
;
153 static /*@exposed@*/ cstring
context_exposeString (flagcode p_flag
) ;
154 static void context_restoreFlagSettings (void) /*@modifies gc@*/ ;
155 static void context_saveFlagSettings (void) /*@modifies gc@*/ ;
156 static void context_exitClauseAux (exprNode p_pred
, exprNode p_tbranch
)
158 static void context_exitClauseSimp (void) /*@modifies gc@*/ ;
159 static void context_exitClausePlain (void) /*@modifies gc@*/ ;
160 static void context_setJustPopped (void) /*@modifies gc.justpopped@*/ ;
161 static void context_setValue (flagcode p_flag
, int p_val
) /*@modifies gc.flags@*/ ;
162 static void context_setFlag (flagcode p_f
, bool p_b
, fileloc p_loc
)
163 /*@modifies gc.flags@*/ ;
166 context_setFlagAux (flagcode p_f
, bool p_b
, bool p_inFile
,
167 bool p_isRestore
, fileloc p_loc
)
168 /*@modifies gc.flags@*/ ;
170 static void context_restoreFlag (flagcode p_f
, fileloc p_loc
)
171 /*@modifies gc.flags@*/ ;
176 cstring
context_unparseFlagMarkers (void)
178 return (flagMarkerList_unparse (gc
.markers
));
180 # endif /* DEADCODE */
182 void context_setPreprocessing (void)
184 llassert (!gc
.preprocessing
);
185 gc
.preprocessing
= TRUE
;
188 void context_clearPreprocessing (void)
190 llassert (gc
.preprocessing
);
191 gc
.preprocessing
= FALSE
;
194 bool context_isPreprocessing (void)
196 return gc
.preprocessing
;
199 bool context_loadingLibrary (void)
201 return (fileloc_isLib (g_currentloc
));
204 bool context_inXHFile (void)
206 return (fileloc_isXHFile (g_currentloc
));
209 void context_setInCommandLine (void)
211 llassert (!gc
.incommandline
);
212 gc
.incommandline
= TRUE
;
215 void context_clearInCommandLine (void)
217 llassert (gc
.incommandline
);
218 gc
.incommandline
= FALSE
;
221 bool context_isInCommandLine (void)
223 return gc
.incommandline
;
227 void pushClause (clause c
) /*@modifies gc.clauses, gc.inclause@*/
230 clauseStack_push (gc
.clauses
, c
);
232 if (clause_isConditional (c
)
233 && context_getFlag (FLG_CONTROLNESTDEPTH
))
235 int maxdepth
= context_getValue (FLG_CONTROLNESTDEPTH
);
236 int depth
= clauseStack_controlDepth (gc
.clauses
);
238 if (depth
== maxdepth
+ 1)
241 (FLG_CONTROLNESTDEPTH
,
242 message ("Maximum control nesting depth "
251 clause
topClause (clauseStack s
) /*@*/
253 if (clauseStack_isEmpty (s
)) return NOCLAUSE
;
254 return ((clause
) clauseStack_top (s
));
258 context_addMacroCache (/*@only@*/ cstring def
)
260 DPRINTF (("macro cache: %s", def
));
261 macrocache_addEntry (gc
.mc
, fileloc_copy (g_currentloc
), def
);
265 context_addComment (/*@only@*/ cstring def
, fileloc loc
)
267 macrocache_addComment (gc
.mc
, fileloc_copy (loc
), def
);
271 ** returns TRUE is fl is in ignore region, or region where -code
273 ** the logic is fuzzy...
277 context_inSuppressFlagZone (fileloc fl
, flagcode code
)
279 ynm ret
= flagMarkerList_suppressError (gc
.markers
, code
, fl
);
282 if (ynm_isMaybe (ret
))
290 res
= !gc
.saveflags
[code
];
294 res
= !context_getFlag (code
);
299 res
= ynm_toBoolStrict (ret
);
306 context_suppressSystemMsg (fileloc fl
)
308 if (context_getFlag (FLG_SYSTEMDIRERRORS
))
314 return (fileloc_isSystemFile (fl
));
319 context_suppressFlagMsg (flagcode flag
, fileloc fl
)
321 if (context_suppressSystemMsg (fl
))
326 DPRINTF (("Checking suppress: %s / %s", fileloc_unparse (fl
), fileloc_unparse (g_currentloc
)));
328 /* want same object compare here */
330 if (fileloc_equal (fl
, g_currentloc
) || gc
.inDerivedFile
)
332 DPRINTF (("In derived file: %s", bool_unparse (gc
.inDerivedFile
)));
334 return (!context_getFlag (flag
)
335 || context_inSuppressRegion ()
336 || context_inSuppressZone (fl
)
337 || (context_inSuppressFlagZone (fl
, flag
))); /* removed gc.inDerivedFile from this */
341 return (context_inSuppressFlagZone (fl
, flag
));
346 context_suppressNotFlagMsg (flagcode flag
, fileloc fl
)
349 if (context_suppressSystemMsg (fl
))
355 if (fl
== g_currentloc
)
356 /*@noaccess fileloc@*/
358 return (context_getFlag (flag
) || context_inSuppressRegion ());
363 return (context_getFlag (flag
) || context_inSuppressRegion ());
368 context_inSuppressZone (fileloc fl
)
370 if (context_suppressSystemMsg (fl
))
375 return (flagMarkerList_inIgnore (gc
.markers
, fl
));
379 context_inSuppressRegion (void)
381 return (gc
.insuppressregion
);
385 context_enterSuppressRegion (fileloc loc
)
387 if (gc
.insuppressregion
)
389 gc
.insuppressregion
= FALSE
; /* get this msg! */
391 ("%q: New ignore errors region entered while in ignore errors region",
392 fileloc_unparse (loc
)));
395 gc
.insuppressregion
= TRUE
;
396 (void) flagMarkerList_add (gc
.markers
, flagMarker_createIgnoreOn (loc
));
400 context_addFlagMarker (flagcode code
, ynm set
, fileloc loc
)
402 (void) flagMarkerList_add (gc
.markers
,
403 flagMarker_createLocalSet (code
, set
, loc
));
407 context_enterSuppressLine (int count
, fileloc loc
)
409 if (context_processingMacros ())
414 if (flagMarkerList_add
416 flagMarker_createIgnoreCount (count
, loc
)))
418 fileloc nextline
= fileloc_copy (loc
);
419 fileloc_nextLine (nextline
);
420 fileloc_setColumn (nextline
, 0);
422 check (flagMarkerList_add (gc
.markers
,
423 flagMarker_createIgnoreOff (nextline
)));
424 fileloc_free (nextline
);
428 void context_checkSuppressCounts (void)
430 if (context_getFlag (FLG_SUPCOUNTS
))
432 flagMarkerList_checkSuppressCounts (gc
.markers
);
436 void context_incLineno (void)
443 context_exitSuppressRegion (fileloc loc
)
445 if (!gc
.insuppressregion
)
449 message ("End ignore errors in region while not ignoring errors"),
453 gc
.insuppressregion
= FALSE
;
454 (void) flagMarkerList_add (gc
.markers
, flagMarker_createIgnoreOff (loc
));
458 context_enterMTfile (void)
464 context_exitMTfile (void)
466 llassert (gc
.kind
== CX_MT
);
471 context_enterLCLfile (void)
474 gc
.facct
= typeIdSet_emptySet ();
478 addModuleAccess (/*@only@*/ cstring fname
, typeIdSet mods
)
482 for (i
= 0; i
< gc
.nmods
; i
++)
484 if (cstring_equal (gc
.moduleaccess
[i
].file
, fname
))
486 gc
.moduleaccess
[i
].daccess
= typeIdSet_union (gc
.moduleaccess
[i
].daccess
, mods
);
487 cstring_free (fname
);
492 if (gc
.nmods
== gc
.maxmods
)
496 gc
.maxmods
= gc
.maxmods
+ DEFAULTMAXMODS
;
497 oldmods
= gc
.moduleaccess
;
499 gc
.moduleaccess
= (maccesst
*) dmalloc (sizeof (*gc
.moduleaccess
) * (gc
.maxmods
));
501 for (i
= 0; i
< gc
.nmods
; i
++)
503 gc
.moduleaccess
[i
] = oldmods
[i
];
509 gc
.moduleaccess
[gc
.nmods
].file
= fname
;
510 gc
.moduleaccess
[gc
.nmods
].daccess
= mods
;
516 insertModuleAccess (cstring fname
, typeId t
)
520 for (i
= 0; i
< gc
.nmods
; i
++)
522 if (cstring_equal (gc
.moduleaccess
[i
].file
, fname
))
524 gc
.moduleaccess
[i
].daccess
= typeIdSet_insert (gc
.moduleaccess
[i
].daccess
, t
);
529 addModuleAccess (cstring_copy (fname
), typeIdSet_single (t
));
533 context_exitLCLfile (void)
535 if (gc
.kind
!= CX_LCLLIB
)
538 fileLib_withoutExtension (fileTable_fileName (currentFile ()), LCL_EXTENSION
);
540 addModuleAccess (fileLib_removePath (lclname
), gc
.facct
);
541 cstring_free (lclname
);
545 gc
.facct
= typeIdSet_emptySet ();
549 context_dumpModuleAccess (FILE *fout
)
553 for (i
= 0; i
< gc
.nmods
; i
++)
555 cstring td
= typeIdSet_dump (gc
.moduleaccess
[i
].daccess
);
557 fprintf (fout
, "%s#%s@\n",
558 cstring_toCharsSafe (gc
.moduleaccess
[i
].file
),
559 cstring_toCharsSafe (td
));
565 bool context_usingPosixLibrary (void)
567 return (gc
.library
== FLG_POSIXLIB
568 || gc
.library
== FLG_POSIXSTRICTLIB
569 || gc
.library
== FLG_UNIXLIB
570 || gc
.library
== FLG_UNIXSTRICTLIB
);
573 bool context_usingAnsiLibrary (void)
575 return (gc
.library
!= FLG_NOLIB
);
578 flagcode
context_getLibrary (void)
583 void context_setLibrary (flagcode code
)
588 /*@observer@*/ cstring
context_selectedLibrary (void)
593 return cstring_makeLiteralTemp (LLSTRICTLIBS_NAME
);
595 return cstring_makeLiteralTemp (LLPOSIXLIBS_NAME
);
596 case FLG_POSIXSTRICTLIB
:
597 return cstring_makeLiteralTemp (LLPOSIXSTRICTLIBS_NAME
);
599 return cstring_makeLiteralTemp (LLUNIXLIBS_NAME
);
600 case FLG_UNIXSTRICTLIB
:
601 return cstring_makeLiteralTemp (LLUNIXSTRICTLIBS_NAME
);
603 return cstring_makeLiteralTemp (LLSTDLIBS_NAME
);
610 context_loadModuleAccess (FILE *in
)
612 char *s
= mstring_create (MAX_DUMP_LINE_LENGTH
);
614 char *name
= mstring_create (MAX_NAME_LENGTH
);
618 while ((reader_readLine (in
, s
, MAX_DUMP_LINE_LENGTH
) != NULL
)
624 while (s
!= NULL
&& *s
!= ';' && *s
!= '\0')
628 while (*s
!= '#' && *s
!= '\0')
637 llcontbug (message ("context_loadModuleAccess: bad library line: %s\n",
638 cstring_fromChars (s
)));
644 addModuleAccess (cstring_copy (cstring_fromChars (oname
)),
645 typeIdSet_undump (&s
));
647 (void) reader_readLine (in
, s
, MAX_DUMP_LINE_LENGTH
);
648 llassert (s
!= lasts
);
656 typeIdSet
context_fileAccessTypes (void)
662 context_resetModeFlags (void)
666 if (flagcode_isModeFlag (code
))
668 context_setFlag (code
, FALSE
, g_currentloc
);
676 ** Set all flags to FALSE, except for a few which are
679 ** Set all values and strings to appropriate defaults.
680 ** Set all counters to 0.
684 conext_resetAllCounters (void)
688 for (i
= 0; i
< NUMVALUEFLAGS
; i
++)
695 context_resetAllFlags (void)
697 DPRINTF (("******** Reset all flags"));
701 gc
.flags
[code
] = FALSE
;
703 if (flagcode_hasNumber (code
))
707 /*@-loopswitchbreak@*/
711 val
= DEFAULT_LIMIT
; break;
713 val
= DEFAULT_BUGSLIMIT
; break;
715 val
= DEFAULT_LINELEN
; break;
716 case FLG_INDENTSPACES
:
717 val
= DEFAULT_INDENTSPACES
; break;
718 case FLG_LOCINDENTSPACES
:
719 val
= DEFAULT_LOCINDENTSPACES
; break;
720 case FLG_EXTERNALNAMELEN
:
721 val
= ISO99_EXTERNALNAMELEN
; break;
722 case FLG_INTERNALNAMELEN
:
723 val
= ISO99_INTERNALNAMELEN
; break;
724 case FLG_COMMENTCHAR
:
725 val
= (int) DEFAULT_COMMENTCHAR
; break;
726 case FLG_CONTROLNESTDEPTH
:
727 val
= (int) ISO99_CONTROLNESTDEPTH
; break;
728 case FLG_STRINGLITERALLEN
:
729 val
= (int) ISO99_STRINGLITERALLEN
; break;
730 case FLG_INCLUDENEST
:
731 val
= (int) ISO99_INCLUDENEST
; break;
732 case FLG_NUMSTRUCTFIELDS
:
733 val
= (int) ISO99_NUMSTRUCTFIELDS
; break;
734 case FLG_NUMENUMMEMBERS
:
735 val
= (int) ISO99_NUMENUMMEMBERS
; break;
740 llbug (message ("Bad value flag: %s", flagcode_unparse (code
)));
742 /*@=loopswitchbreak@*/
744 DPRINTF (("Set value: [%s] / %d", flagcode_unparse (code
), val
));
745 context_setValue (code
, val
);
746 DPRINTF (("Set value: [%s] / %d", flagcode_unparse (code
), context_getValue (code
)));
747 llassert (context_getValue (code
) == val
);
749 else if (flagcode_hasChar (code
))
751 llassert (code
== FLG_COMMENTCHAR
);
752 context_setCommentMarkerChar (DEFAULT_COMMENTCHAR
);
754 else if (flagcode_hasString (code
))
756 cstring val
= cstring_undefined
;
759 { /*@-loopswitchbreak@*/
762 cstring larchpath
= cstring_makeLiteralTemp (getenv (LARCH_PATH
));
764 if (cstring_isDefined (larchpath
))
766 val
= cstring_copy (larchpath
);
770 val
= osd_pathListConcat (".", PKGDATADIR CONNECTSTR DEFAULT_LARCHDIR
);
775 case FLG_LCLIMPORTDIR
:
777 cstring lclimpordir
= cstring_makeLiteralTemp (getenv (LCLIMPORTDIR
));
779 if (cstring_isDefined (lclimpordir
))
781 val
= cstring_copy (lclimpordir
);
785 val
= osd_pathListConcat (".", PKGDATADIR CONNECTSTR DEFAULT_LCLDIR
);
791 val
= osd_getTempDir(); break;
793 val
= cstring_makeLiteral (DEFAULT_BOOLTYPE
); break;
795 val
= cstring_makeLiteral ("false"); break;
797 val
= cstring_makeLiteral ("true"); break;
798 case FLG_MACROVARPREFIX
:
799 val
= cstring_makeLiteral ("m_"); break;
801 val
= cstring_makeLiteral (DEFAULT_SYSTEMDIRS
); break;
804 } /*@=loopswitchbreak@*/
806 context_setString (code
, val
);
810 ; /* nothing to set */
815 ** These flags are true by default.
818 /* eventually, move this into flags.def */
820 gc
.flags
[FLG_STREAMOVERWRITE
] = TRUE
;
821 gc
.flags
[FLG_OBVIOUSLOOPEXEC
] = TRUE
;
822 gc
.flags
[FLG_MODIFIES
] = TRUE
;
823 gc
.flags
[FLG_NESTCOMMENT
] = TRUE
;
824 gc
.flags
[FLG_GLOBALS
] = TRUE
;
825 gc
.flags
[FLG_FULLINITBLOCK
] = TRUE
;
826 gc
.flags
[FLG_INITSIZE
] = TRUE
;
827 gc
.flags
[FLG_INITALLELEMENTS
] = TRUE
;
828 gc
.flags
[FLG_NULLINIT
] = TRUE
;
830 gc
.flags
[FLG_STRINGLITTOOLONG
] = TRUE
;
831 gc
.flags
[FLG_MACROCONSTDIST
] = TRUE
;
832 gc
.flags
[FLG_LIKELYBOOL
] = TRUE
;
833 gc
.flags
[FLG_ZEROPTR
] = TRUE
;
834 gc
.flags
[FLG_NUMLITERAL
] = TRUE
;
835 gc
.flags
[FLG_DUPLICATEQUALS
] = TRUE
;
836 gc
.flags
[FLG_SKIPISOHEADERS
] = TRUE
;
837 gc
.flags
[FLG_SKIPPOSIXHEADERS
] = FALSE
;
838 gc
.flags
[FLG_SYSTEMDIREXPAND
] = TRUE
;
839 gc
.flags
[FLG_UNRECOGCOMMENTS
] = TRUE
;
840 gc
.flags
[FLG_UNRECOGFLAGCOMMENTS
] = TRUE
;
841 gc
.flags
[FLG_CASTFCNPTR
] = TRUE
;
842 gc
.flags
[FLG_DOLCS
] = TRUE
;
843 gc
.flags
[FLG_USEVARARGS
] = TRUE
;
844 gc
.flags
[FLG_MAINTYPE
] = TRUE
;
845 gc
.flags
[FLG_SPECMACROS
] = TRUE
;
846 gc
.flags
[FLG_REDEF
] = TRUE
;
847 gc
.flags
[FLG_MACRONEXTLINE
] = TRUE
;
849 gc
.flags
[FLG_SIZEOFFORMALARRAY
] = TRUE
;
850 gc
.flags
[FLG_FIXEDFORMALARRAY
] = TRUE
;
852 gc
.flags
[FLG_UNRECOGDIRECTIVE
] = TRUE
;
853 gc
.flags
[FLG_WARNUSE
] = TRUE
;
854 gc
.flags
[FLG_PREDASSIGN
] = TRUE
;
855 gc
.flags
[FLG_MODOBSERVER
] = TRUE
;
856 gc
.flags
[FLG_MACROVARPREFIXEXCLUDE
] = TRUE
;
857 gc
.flags
[FLG_EXTERNALNAMECASEINSENSITIVE
] = TRUE
;
859 gc
.flags
[FLG_PARAMIMPTEMP
] = TRUE
;
860 gc
.flags
[FLG_RETIMPONLY
] = TRUE
;
861 gc
.flags
[FLG_GLOBIMPONLY
] = TRUE
;
862 gc
.flags
[FLG_STRUCTIMPONLY
] = TRUE
;
863 gc
.flags
[FLG_PREPROC
] = TRUE
;
864 gc
.flags
[FLG_NAMECHECKS
] = TRUE
;
865 gc
.flags
[FLG_FORMATCODE
] = TRUE
;
866 gc
.flags
[FLG_FORMATTYPE
] = TRUE
;
867 gc
.flags
[FLG_BADFLAG
] = TRUE
;
868 gc
.flags
[FLG_WARNFLAGS
] = TRUE
;
869 gc
.flags
[FLG_WARNRC
] = TRUE
;
870 gc
.flags
[FLG_FILEEXTENSIONS
] = TRUE
;
871 gc
.flags
[FLG_WARNUNIXLIB
] = FALSE
;
872 gc
.flags
[FLG_WARNPOSIX
] = TRUE
;
873 gc
.flags
[FLG_SHOWCOL
] = TRUE
;
874 gc
.flags
[FLG_SHOWDEEPHISTORY
] = FALSE
; /* TRUE; */
875 gc
.flags
[FLG_SHOWFUNC
] = TRUE
;
876 gc
.flags
[FLG_SUPCOUNTS
] = TRUE
;
877 gc
.flags
[FLG_HINTS
] = TRUE
;
878 gc
.flags
[FLG_SYNTAX
] = TRUE
;
879 gc
.flags
[FLG_TYPE
] = TRUE
;
880 gc
.flags
[FLG_INCOMPLETETYPE
] = TRUE
;
881 gc
.flags
[FLG_ABSTRACT
] = TRUE
;
882 gc
.flags
[FLG_NUMABSTRACT
] = TRUE
;
883 gc
.flags
[FLG_ITERBALANCE
] = TRUE
;
884 gc
.flags
[FLG_ITERYIELD
] = TRUE
;
885 gc
.flags
[FLG_DUPLICATECASES
] = TRUE
;
886 gc
.flags
[FLG_ALWAYSEXITS
] = TRUE
;
887 gc
.flags
[FLG_EMPTYRETURN
] = TRUE
;
888 gc
.flags
[FLG_MACRORETURN
] = TRUE
;
889 gc
.flags
[FLG_UNRECOG
] = TRUE
;
890 gc
.flags
[FLG_SYSTEMUNRECOG
] = TRUE
;
891 gc
.flags
[FLG_LINTCOMMENTS
] = TRUE
;
892 gc
.flags
[FLG_ACCESSCZECH
] = TRUE
;
893 gc
.flags
[FLG_ACCESSMODULE
] = TRUE
;
894 gc
.flags
[FLG_ACCESSFILE
] = TRUE
;
895 gc
.flags
[FLG_MACROVARPREFIX
] = TRUE
;
897 gc
.flags
[FLG_ANNOTATIONERROR
] = TRUE
;
898 gc
.flags
[FLG_COMMENTERROR
] = TRUE
;
901 ** Changed for version 2.4.
904 gc
.flags
[FLG_GNUEXTENSIONS
] = TRUE
;
910 /* commenting ou until some output issues are fixed */
911 gc
.flags
[FLG_ORCONSTRAINT
] = TRUE
;
913 gc
.flags
[FLG_CONSTRAINTLOCATION
] = TRUE
;
916 gc
.flags
[FLG_WARNSYSFILES
] = TRUE
;
919 ** On by default for Win32, but not Unix
922 # if defined (WIN32) || defined (OS2)
923 gc
.flags
[FLG_PARENFILEFORMAT
] = TRUE
;
924 gc
.flags
[FLG_CASEINSENSITIVEFILENAMES
] = TRUE
;
929 ** C is way-lame, and you can initialize an array to a constant except where
930 ** it is declared. Hence, a macro is used to set the modeflags.
934 # define SETFLAGS() \
935 { int i = 0; while (modeflags[i] != INVALID_FLAG) { \
936 if (!flagcode_isModeFlag (modeflags[i])) \
937 { llbug (message ("not a mode flag: %s", \
938 flagcode_unparse (modeflags[i]))); } \
939 else { context_setFlag (modeflags[i], TRUE, g_currentloc); } i++; }}
941 static void context_setModeAux (cstring p_s
, bool p_warn
) ;
944 context_setMode (cstring s
)
946 context_setModeAux (s
, TRUE
);
950 context_setModeNoWarn (cstring s
)
952 context_setModeAux (s
, FALSE
);
956 context_setModeAux (cstring s
, bool warn
)
958 intSet setflags
= intSet_new ();
962 if (flagcode_isModeFlag (code
))
964 if (gc
.setGlobally
[code
])
966 (void) intSet_insert (setflags
, (int) code
);
971 if (!intSet_isEmpty (setflags
))
973 cstring rflags
= cstring_undefined
;
976 intSet_elements (setflags
, el
)
978 if (cstring_isUndefined (rflags
))
980 rflags
= cstring_copy (flagcode_unparse ((flagcode
) (el
)));
984 rflags
= message ("%q, %s", rflags
,
985 flagcode_unparse ((flagcode
) el
));
989 if (num
> 4 && intSet_size (setflags
) > 6)
991 rflags
= message ("%q, (%d others) ...", rflags
,
992 intSet_size (setflags
) - num
);
995 } end_intSet_elements
;
999 voptgenerror (FLG_WARNFLAGS
,
1000 message ("Setting mode %s after setting mode flags will "
1001 "override set values of flags: %s",
1006 cstring_free (rflags
);
1009 intSet_free (setflags
);
1011 context_resetModeFlags ();
1013 if (cstring_equalLit (s
, "standard"))
1015 flagcode modeflags
[] =
1017 FLG_ENUMINT
, FLG_MACROMATCHNAME
,
1018 FLG_STRINGLITNOROOM
,
1019 FLG_STRINGLITNOROOMFINALNULL
,
1020 FLG_MACROUNDEF
, FLG_RELAXQUALS
,
1021 FLG_USEALLGLOBS
, FLG_CHECKSTRICTGLOBALS
,
1022 FLG_CHECKSTRICTGLOBALIAS
,
1023 FLG_CHECKEDGLOBALIAS
,
1024 FLG_CHECKMODGLOBALIAS
,
1025 FLG_PREDBOOLOTHERS
, FLG_PREDBOOLINT
,
1026 FLG_UNSIGNEDCOMPARE
,
1027 FLG_PARAMUNUSED
, FLG_VARUNUSED
, FLG_FUNCUNUSED
,
1029 FLG_ABSTRACTCOMPARE
,
1030 FLG_CONSTUNUSED
, FLG_ENUMMEMUNUSED
, FLG_FIELDUNUSED
,
1031 FLG_PTRNUMCOMPARE
, FLG_BOOLCOMPARE
, FLG_UNSIGNEDCOMPARE
,
1032 FLG_MUTREP
, FLG_NOEFFECT
, FLG_IMPTYPE
,
1033 FLG_RETVALOTHER
, FLG_RETVALBOOL
, FLG_RETVALINT
,
1034 FLG_SPECUNDEF
, FLG_INCONDEFS
, FLG_INCONDEFSLIB
, FLG_MISPLACEDSHAREQUAL
,
1037 FLG_MACROPARAMS
, FLG_MACROASSIGN
, FLG_SEFPARAMS
,
1038 FLG_MACROSTMT
, FLG_MACROPARENS
,
1041 FLG_MACROREDEF
, FLG_INFLOOPS
, FLG_UNREACHABLE
,
1042 FLG_NORETURN
, FLG_CASEBREAK
, FLG_MISSCASE
, FLG_USEDEF
,
1048 /* memchecks flags */
1050 FLG_NULLSTATE
, FLG_NULLASSIGN
,
1051 FLG_NULLPASS
, FLG_NULLRET
,
1054 FLG_COMPDEF
, FLG_COMPMEMPASS
, FLG_UNIONDEF
,
1057 /* memtrans flags */
1073 FLG_NUMABSTRACTCAST
,
1076 FLG_USERELEASED
, FLG_ALIASUNIQUE
, FLG_MAYALIASUNIQUE
,
1079 FLG_MUSTDEFINE
, FLG_GLOBSTATE
,
1080 FLG_COMPDESTROY
, FLG_MUSTNOTALIAS
,
1083 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1084 FLG_EVALORDER
, FLG_SHADOW
, FLG_READONLYSTRINGS
,
1086 FLG_IMPCHECKEDSPECGLOBALS
,
1087 FLG_MODGLOBS
, FLG_WARNLINTCOMMENTS
,
1088 FLG_IFEMPTY
, FLG_REALCOMPARE
,
1089 FLG_BOOLOPS
, FLG_PTRNEGATE
,
1091 FLG_SHIFTIMPLEMENTATION
,
1092 FLG_BUFFEROVERFLOWHIGH
,
1099 else if (cstring_equalLit (s
, "weak"))
1101 flagcode modeflags
[] =
1103 FLG_BOOLINT
, FLG_CHARINT
, FLG_FLOATDOUBLE
, FLG_LONGINT
, FLG_SHORTINT
,
1104 FLG_ENUMINT
, FLG_RELAXQUALS
, FLG_FORWARDDECL
,
1105 FLG_CHARINDEX
, FLG_NUMABSTRACTINDEX
, FLG_ABSTVOIDP
, FLG_USEALLGLOBS
,
1106 FLG_CHARUNSIGNEDCHAR
,
1109 FLG_VARUNUSED
, FLG_FUNCUNUSED
,
1111 FLG_CHECKSTRICTGLOBALS
, FLG_MACROMATCHNAME
,
1114 FLG_BUFFEROVERFLOWHIGH
,
1115 FLG_RETSTACK
, FLG_PTRNEGATE
,
1116 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1117 FLG_LONGUNSIGNEDINTEGRAL
,
1118 FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL
,
1122 FLG_BUFFEROVERFLOWHIGH
,
1123 FLG_STRINGLITNOROOM
,
1124 FLG_STRINGLITNOROOMFINALNULL
,
1130 else if (cstring_equalLit (s
, "checks"))
1132 flagcode modeflags
[] =
1134 FLG_EXPORTLOCAL
, FLG_IMPTYPE
,
1135 FLG_NUMABSTRACTCAST
,
1136 FLG_ABSTRACTCOMPARE
,
1137 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1138 FLG_CHECKSTRICTGLOBALIAS
,
1139 FLG_CHECKEDGLOBALIAS
,
1140 FLG_CHECKMODGLOBALIAS
,
1141 FLG_UNCHECKEDGLOBALIAS
,
1143 FLG_STRINGLITNOROOM
,
1144 FLG_STRINGLITNOROOMFINALNULL
,
1145 FLG_STRINGLITSMALLER
,
1146 FLG_EXITARG
, FLG_PTRNUMCOMPARE
,
1147 FLG_BOOLCOMPARE
, FLG_UNSIGNEDCOMPARE
,
1148 FLG_MACROUNDEF
, FLG_MUSTMOD
, FLG_ALLGLOBALS
,
1149 FLG_PREDBOOLOTHERS
, FLG_PREDBOOLPTR
, FLG_PREDBOOLINT
,
1150 FLG_USEALLGLOBS
, FLG_MUTREP
, FLG_RETALIAS
,
1151 FLG_RETEXPOSE
, FLG_ASSIGNEXPOSE
, FLG_CASTEXPOSE
,
1152 FLG_FUNCUNUSED
, FLG_GLOBALSIMPMODIFIESNOTHING
,
1153 FLG_TYPEUNUSED
, FLG_FIELDUNUSED
, FLG_PARAMUNUSED
, FLG_VARUNUSED
,
1154 FLG_CONSTUNUSED
, FLG_ENUMMEMUNUSED
,
1155 FLG_NOEFFECT
, FLG_EXPORTHEADER
, FLG_EXPORTHEADERVAR
,
1156 FLG_RETVALOTHER
, FLG_RETVALBOOL
, FLG_RETVALINT
,
1157 FLG_SPECUNDEF
, FLG_IMPCHECKMODINTERNALS
,
1158 FLG_DECLUNDEF
, FLG_INCONDEFS
, FLG_INCONDEFSLIB
,
1159 FLG_MISPLACEDSHAREQUAL
, FLG_REDUNDANTSHAREQUAL
,
1160 FLG_NUMABSTRACTPRINT
,
1167 FLG_SEFPARAMS
, FLG_SEFUNSPEC
, FLG_MACROSTMT
, FLG_MACROPARENS
,
1171 FLG_INFLOOPS
, FLG_INFLOOPSUNCON
,
1173 FLG_NORETURN
, FLG_CASEBREAK
, FLG_MISSCASE
,
1174 FLG_EVALORDER
, FLG_USEDEF
,
1177 /* warn use flags */
1178 FLG_MULTITHREADED
, FLG_PORTABILITY
, FLG_SUPERUSER
, FLG_IMPLEMENTATIONOPTIONAL
,
1179 FLG_BUFFEROVERFLOWHIGH
,
1181 /* memchecks flags */
1183 FLG_NULLSTATE
, FLG_NULLDEREF
, FLG_NULLASSIGN
,
1184 FLG_NULLPASS
, FLG_NULLRET
,
1187 FLG_COMPDEF
, FLG_COMPMEMPASS
, FLG_UNIONDEF
, FLG_RETSTACK
,
1189 /* memtrans flags */
1203 FLG_STATICINITTRANS
,
1204 FLG_UNKNOWNINITTRANS
,
1207 FLG_ONLYUNQGLOBALTRANS
,
1208 FLG_USERELEASED
, FLG_ALIASUNIQUE
, FLG_MAYALIASUNIQUE
,
1211 FLG_MUSTDEFINE
, FLG_GLOBSTATE
,
1212 FLG_COMPDESTROY
, FLG_MUSTNOTALIAS
,
1215 FLG_NULLPOINTERARITH
,
1216 FLG_SHADOW
, FLG_DEPARRAYS
,
1217 FLG_REDECL
, FLG_READONLYSTRINGS
, FLG_READONLYTRANS
,
1218 FLG_LOOPLOOPBREAK
, FLG_SWITCHLOOPBREAK
, FLG_MODGLOBS
,
1219 FLG_CHECKSTRICTGLOBALS
, FLG_IMPCHECKEDSPECGLOBALS
,
1220 FLG_MACROMATCHNAME
, FLG_WARNLINTCOMMENTS
,
1221 FLG_INCLUDENEST
, FLG_ISORESERVED
, FLG_CPPNAMES
,
1222 FLG_NOPARAMS
, FLG_IFEMPTY
, FLG_WHILEEMPTY
, FLG_REALCOMPARE
, FLG_REALRELATECOMPARE
,
1223 FLG_BOOLOPS
, FLG_SHIFTNEGATIVE
,
1224 FLG_SHIFTIMPLEMENTATION
,
1225 FLG_BUFFEROVERFLOWHIGH
, FLG_BUFFEROVERFLOW
,
1230 else if (cstring_equalLit (s
, "strict"))
1232 flagcode modeflags
[] =
1234 FLG_ABSTRACTCOMPARE
,
1235 FLG_CHECKSTRICTGLOBALIAS
,
1236 FLG_NUMABSTRACTCAST
,
1237 FLG_CHECKEDGLOBALIAS
,
1238 FLG_CHECKMODGLOBALIAS
,
1239 FLG_UNCHECKEDGLOBALIAS
,
1243 FLG_NUMABSTRACTPRINT
,
1244 FLG_STRINGLITNOROOM
,
1245 FLG_STRINGLITNOROOMFINALNULL
,
1246 FLG_STRINGLITSMALLER
,
1247 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1248 FLG_MACROUNDEF
, FLG_MUTREP
, FLG_MUSTMOD
,
1249 FLG_ALLGLOBALS
, FLG_IMPTYPE
,
1250 FLG_MODNOMODS
, FLG_MODGLOBSUNSPEC
, FLG_MODSTRICTGLOBSUNSPEC
,
1251 FLG_GLOBUNSPEC
, FLG_SIZEOFTYPE
,
1252 FLG_EXPORTHEADER
, FLG_EXPORTHEADERVAR
,
1253 FLG_NOPARAMS
, FLG_OLDSTYLE
, FLG_EXITARG
,
1256 FLG_ONLYUNQGLOBALTRANS
,
1257 FLG_GLOBALSIMPMODIFIESNOTHING
,
1258 FLG_PREDBOOLOTHERS
, FLG_PREDBOOLPTR
, FLG_PREDBOOLINT
,
1259 FLG_INTERNALGLOBS
, FLG_INTERNALGLOBSNOGLOBS
,
1260 FLG_USEALLGLOBS
, FLG_RETALIAS
,
1261 FLG_MODGLOBS
, FLG_MODGLOBSUNSPEC
, FLG_MODGLOBSUNCHECKED
,
1262 FLG_RETEXPOSE
, FLG_ASSIGNEXPOSE
, FLG_CASTEXPOSE
,
1263 FLG_NOEFFECTUNCON
, FLG_EVALORDERUNCON
,
1265 FLG_EXPORTITER
, FLG_EXPORTCONST
,
1266 FLG_TYPEUNUSED
, FLG_FIELDUNUSED
, FLG_PARAMUNUSED
, FLG_TOPUNUSED
,
1267 FLG_CONSTUNUSED
, FLG_ENUMMEMUNUSED
,
1269 FLG_NULLPOINTERARITH
, FLG_POINTERARITH
,
1271 FLG_BOOLCOMPARE
, FLG_UNSIGNEDCOMPARE
,
1272 FLG_NOEFFECT
, FLG_RETVALINT
, FLG_RETVALBOOL
, FLG_RETVALOTHER
,
1273 FLG_ISORESERVED
, FLG_ISORESERVEDLOCAL
, FLG_CPPNAMES
,
1274 FLG_RETVALBOOL
, FLG_RETVALINT
, FLG_SPECUNDEF
,
1275 FLG_DECLUNDEF
, FLG_STRICTOPS
, FLG_INCONDEFS
,
1276 FLG_MISPLACEDSHAREQUAL
, FLG_REDUNDANTSHAREQUAL
,
1277 FLG_INCONDEFSLIB
, FLG_MATCHFIELDS
, FLG_EXPORTMACRO
, FLG_EXPORTVAR
,
1278 FLG_EXPORTFCN
, FLG_EXPORTTYPE
, FLG_EXPORTLOCAL
, FLG_MACROPARAMS
,
1280 FLG_SEFPARAMS
, FLG_SEFUNSPEC
, FLG_MACROSTMT
, FLG_MACROPARENS
,
1283 FLG_MACROREDEF
, FLG_MACROEMPTY
,
1284 FLG_INFLOOPS
, FLG_INFLOOPSUNCON
,
1286 FLG_NORETURN
, FLG_CASEBREAK
, FLG_MISSCASE
, FLG_USEDEF
,
1288 FLG_MODUNCON
, FLG_MODUNCONNOMODS
, FLG_MODINTERNALSTRICT
,
1289 FLG_MODOBSERVERUNCON
,
1294 /* warn use flags */
1295 FLG_MULTITHREADED
, FLG_PORTABILITY
, FLG_SUPERUSER
, FLG_IMPLEMENTATIONOPTIONAL
,
1296 FLG_BUFFEROVERFLOWHIGH
,
1297 FLG_BUFFEROVERFLOW
, FLG_TOCTOU
,
1299 /* memchecks flags */
1300 FLG_NULLSTATE
, FLG_NULLDEREF
, FLG_NULLASSIGN
,
1301 FLG_NULLPASS
, FLG_NULLRET
,
1303 FLG_COMPDEF
, FLG_COMPMEMPASS
, FLG_UNIONDEF
,
1305 /* memory checking flags */
1306 FLG_BOUNDSREAD
, FLG_BOUNDSWRITE
,
1307 FLG_LIKELYBOUNDSREAD
, FLG_LIKELYBOUNDSWRITE
,
1310 /* memtrans flags */
1326 FLG_STATICINITTRANS
,
1327 FLG_UNKNOWNINITTRANS
,
1329 FLG_USERELEASED
, FLG_ALIASUNIQUE
, FLG_MAYALIASUNIQUE
,
1332 FLG_MUSTDEFINE
, FLG_GLOBSTATE
,
1333 FLG_COMPDESTROY
, FLG_MUSTNOTALIAS
,
1337 FLG_DECLPARAMNAME
, FLG_DECLPARAMMATCH
,
1339 FLG_SHADOW
, FLG_DEPARRAYS
,
1340 FLG_STRICTDESTROY
, FLG_STRICTUSERELEASED
, FLG_STRICTBRANCHSTATE
,
1341 FLG_REDECL
, FLG_READONLYSTRINGS
, FLG_READONLYTRANS
,
1342 FLG_LOOPLOOPBREAK
, FLG_LOOPSWITCHBREAK
, FLG_SWITCHLOOPBREAK
,
1343 FLG_SWITCHSWITCHBREAK
, FLG_LOOPLOOPCONTINUE
,
1344 FLG_CHECKSTRICTGLOBALS
, FLG_IMPCHECKEDSPECGLOBALS
,
1345 FLG_ALLGLOBALS
, FLG_IMPCHECKEDSTRICTGLOBALS
,
1346 FLG_IMPCHECKEDSTRICTSTATICS
,
1347 FLG_IMPCHECKEDSTRICTSPECGLOBALS
,
1348 FLG_IMPCHECKMODINTERNALS
,
1349 FLG_WARNMISSINGGLOBALS
, FLG_WARNMISSINGGLOBALSNOGLOBS
,
1350 FLG_WARNLINTCOMMENTS
, FLG_ISORESERVEDLOCAL
,
1351 FLG_INCLUDENEST
, FLG_STRINGLITERALLEN
,
1352 FLG_NUMSTRUCTFIELDS
, FLG_NUMENUMMEMBERS
,
1353 FLG_CONTROLNESTDEPTH
,
1354 FLG_FORBLOCK
, FLG_WHILEBLOCK
,
1355 FLG_FOREMPTY
, FLG_WHILEEMPTY
,
1356 FLG_IFEMPTY
, FLG_IFBLOCK
,
1358 FLG_REALCOMPARE
, FLG_BOOLOPS
, FLG_REALRELATECOMPARE
,
1359 FLG_SYSTEMDIRERRORS
, FLG_UNUSEDSPECIAL
,
1362 FLG_SHIFTIMPLEMENTATION
,
1364 FLG_BUFFEROVERFLOWHIGH
, FLG_BUFFEROVERFLOW
,
1372 llcontbug (message ("context_setMode: bad mode: %s", s
));
1377 context_isSpecialFile (cstring fname
)
1379 cstring ext
= fileLib_getExtension (fname
);
1381 return (cstring_equalLit (ext
, ".y")
1382 || cstring_equalLit (ext
, ".l")
1383 || cstring_equalLit (fname
, "lex.yy.c"));
1387 context_isSystemDir (cstring dir
)
1389 return osd_pathPrefixInPathList (dir
, context_getString (FLG_SYSTEMDIRS
));
1393 context_addFileAccessType (typeId t
)
1397 if (context_inFunctionLike ())
1399 gc
.acct
= typeIdSet_insert (gc
.acct
, t
);
1402 gc
.facct
= typeIdSet_insert (gc
.facct
, t
);
1404 base
= fileloc_getBase (g_currentloc
);
1405 insertModuleAccess (base
, t
);
1406 DPRINTF (("Add file access: %s / %s", typeIdSet_unparse (gc
.facct
),
1407 typeIdSet_unparse (gc
.acct
)));
1411 context_removeFileAccessType (typeId t
)
1413 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
1414 || gc
.kind
== CX_UNKNOWNMACRO
)
1416 gc
.acct
= typeIdSet_removeFresh (gc
.acct
, t
);
1419 gc
.facct
= typeIdSet_removeFresh (gc
.facct
, t
);
1420 gc
.nacct
= typeIdSet_insert (gc
.nacct
, t
);
1423 void context_enterFunctionHeader (void)
1425 if (context_getFlag (FLG_GRAMMAR
))
1427 lldiagmsg (message ("Enter function header: %q", context_unparse ()));
1430 if (gc
.kind
!= CX_GLOBAL
)
1432 llparseerror (cstring_makeLiteral
1433 ("Likely parse error. Function header outside global context."));
1437 llassert (gc
.kind
== CX_GLOBAL
);
1438 DPRINTF (("Enter function header!"));
1439 gc
.inFunctionHeader
= TRUE
;
1443 void context_exitFunctionHeader (void)
1445 if (context_getFlag (FLG_GRAMMAR
))
1447 lldiagmsg (message ("Exit function header: %q", context_unparse ()));
1450 DPRINTF (("Exit function header!"));
1451 gc
.inFunctionHeader
= FALSE
;
1454 bool context_inFunctionHeader (void)
1456 return (gc
.inFunctionHeader
);
1459 void context_enterFunctionDeclaration (uentry e
)
1461 if (context_getFlag (FLG_GRAMMAR
))
1463 lldiagmsg (message ("Enter function declaration: %q", context_unparse ()));
1466 DPRINTF (("Enter function decl"));
1467 llassert (gc
.savekind
== CX_ERROR
);
1468 gc
.savekind
= gc
.kind
;
1469 gc
.savecont
= gc
.cont
;
1470 gc
.kind
= CX_FCNDECLARATION
;
1474 void context_exitFunctionDeclaration (void)
1476 if (context_getFlag (FLG_GRAMMAR
))
1478 lldiagmsg (message ("Exit function declaration: %q", context_unparse ()));
1481 DPRINTF (("Exit function decl"));
1482 llassert (gc
.savekind
!= CX_ERROR
);
1483 llassert (gc
.kind
== CX_FCNDECLARATION
);
1484 gc
.kind
= gc
.savekind
;
1485 gc
.cont
= gc
.savecont
;
1487 gc
.savekind
= CX_ERROR
;
1489 if (context_getFlag (FLG_GRAMMAR
))
1491 lldiagmsg (message ("After exit function declaration: %q", context_unparse ()));
1496 bool context_inFunctionDeclaration (void)
1498 return (gc
.kind
== CX_FCNDECLARATION
);
1500 # endif /* DEADCODE */
1503 context_enterMacro (/*@observer@*/ uentry e
)
1505 context_enterFunction (e
);
1506 gc
.kind
= CX_MACROFCN
;
1510 context_enterUnknownMacro (/*@dependent@*/ uentry e
)
1512 llassert (uentry_isFunction (e
));
1513 context_enterFunction (e
);
1514 gc
.kind
= CX_UNKNOWNMACRO
;
1517 void context_enterAndClause (exprNode e
)
1519 DPRINTF (("enter and clause: %s", exprNode_unparse (e
)));
1520 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e
)));
1521 pushClause (ANDCLAUSE
);
1524 void context_enterOrClause (exprNode e
)
1526 usymtab_trueBranch (guardSet_invert (exprNode_getGuards (e
)));
1527 pushClause (ORCLAUSE
);
1530 bool context_inDeepLoop (void)
1532 bool inLoop
= FALSE
;
1534 clauseStack_elements (gc
.clauses
, el
)
1536 if (clause_isLoop (el
))
1545 } end_clauseStack_elements
;
1550 bool context_inDeepSwitch (void)
1552 bool inLoop
= FALSE
;
1554 clauseStack_elements (gc
.clauses
, el
)
1556 if (clause_isSwitch (el
))
1565 } end_clauseStack_elements
;
1570 bool context_inDeepLoopSwitch (void)
1572 bool inLoop
= FALSE
;
1574 clauseStack_elements (gc
.clauses
, el
)
1576 if (clause_isBreakable (el
))
1585 } end_clauseStack_elements
;
1590 clause
context_breakClause (void)
1592 clauseStack_elements (gc
.clauses
, el
)
1594 if (clause_isSwitch (el
))
1598 else if (clause_isLoop (el
))
1606 } end_clauseStack_elements
;
1611 clause
context_nextBreakClause (void)
1613 bool hasOne
= FALSE
;
1615 clauseStack_elements (gc
.clauses
, el
)
1617 if (clause_isBreakable (el
))
1628 } end_clauseStack_elements
;
1633 bool context_inConditional (void)
1635 clauseStack_elements (gc
.clauses
, el
)
1638 ** Should also include TRUECLAUSE and FALSECLAUSE, but need
1639 ** to distinguish if from ? for this
1642 if (clause_isBreakable (el
) && (el
!= DOWHILECLAUSE
))
1646 } end_clauseStack_elements
;
1651 void context_exitAndClause (exprNode pred
, exprNode tbranch
)
1653 context_setJustPopped ();
1655 llassert (gc
.inclause
== ANDCLAUSE
);
1657 usymtab_popAndBranch (pred
, tbranch
);
1658 clauseStack_pop (gc
.clauses
);
1659 gc
.inclause
= topClause (gc
.clauses
);
1662 void context_exitOrClause (exprNode pred
, exprNode tbranch
)
1664 context_setJustPopped ();
1666 llassert (gc
.inclause
== ORCLAUSE
);
1668 usymtab_popOrBranch (pred
, tbranch
);
1669 clauseStack_pop (gc
.clauses
);
1670 gc
.inclause
= topClause (gc
.clauses
);
1673 static void context_enterCondClauseAux (clause cl
)
1679 static void context_enterTrueAux (exprNode e
, clause cl
)
1682 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e
)));
1686 void context_enterIterClause (void)
1688 context_enterTrueAux (exprNode_undefined
, ITERCLAUSE
);
1691 void context_enterDoWhileClause (void)
1693 pushClause (DOWHILECLAUSE
);
1696 void context_enterWhileClause (exprNode e
)
1698 context_enterTrueAux (e
, WHILECLAUSE
);
1701 void context_enterForClause (exprNode e
)
1703 context_enterTrueAux (e
, FORCLAUSE
);
1706 void context_enterTrueClause (exprNode e
)
1708 context_enterTrueAux (e
, TRUECLAUSE
);
1711 void context_enterSwitch (exprNode e
)
1713 DPRINTF (("Enter switch: %s", exprNode_unparse (e
)));
1714 usymtab_switchBranch (e
);
1715 context_enterCondClauseAux (SWITCHCLAUSE
);
1718 void context_exitSwitch (exprNode e
, bool allpaths
)
1720 usymtab_exitSwitch (e
, allpaths
);
1722 while (clause_isCase (clauseStack_top (gc
.clauses
)))
1724 clauseStack_pop (gc
.clauses
);
1727 context_exitClauseSimp ();
1730 void context_enterCaseClause (exprNode e
)
1732 bool branch
= FALSE
;
1734 DPRINTF (("Enter case clause!"));
1736 branch
= usymtab_newCase (exprNode_undefined
, e
);
1740 context_enterCondClauseAux (CASECLAUSE
);
1744 static void context_enterFalseClauseAux (exprNode e
, clause cl
)
1747 usymtab_altBranch (guardSet_invert (exprNode_getGuards (e
)));
1749 clauseStack_switchTop (gc
.clauses
, cl
);
1752 void context_enterFalseClause (exprNode e
)
1755 context_enterFalseClauseAux (e
, FALSECLAUSE
);
1759 context_enterConstantMacro (/*@exposed@*/ /*@dependent@*/ uentry e
)
1761 gc
.kind
= CX_MACROCONST
;
1763 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1765 gc
.acct
= typeIdSet_subtract (typeIdSet_union (gc
.facct
, uentry_accessType (e
)),
1769 usymtab_enterScope ();
1770 sRef_enterFunctionScope ();
1772 gc
.globs
= globSet_undefined
;
1773 globSet_clear (gc
.globs_used
);
1774 gc
.mods
= sRefSet_undefined
;
1777 uentry
context_getHeader (void)
1779 if (!(context_inFunctionLike () || (gc
.kind
== CX_MACROCONST
)))
1781 llfatalbug (message ("context_getHeader: bad call: %q",
1782 context_unparse ()));
1785 return (gc
.cont
.fcn
);
1789 context_setFunctionDefined (fileloc loc
)
1793 case CX_UNKNOWNMACRO
:
1796 uentry_setFunctionDefined (gc
.cont
.fcn
, loc
);
1799 /* (not a bug because of parse errors) */
1805 context_enterFunction (/*@exposed@*/ uentry e
)
1807 gc
.kind
= CX_FUNCTION
;
1810 DPRINTF (("Enter function: %s", uentry_unparse (e
)));
1812 if (uentry_hasAccessType (e
))
1814 gc
.acct
= typeIdSet_subtract (typeIdSet_union (gc
.facct
, uentry_accessType (e
)),
1822 DPRINTF (("Enter function: %s / %s", uentry_unparse (e
),
1823 typeIdSet_unparse (gc
.acct
)));
1825 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1827 gc
.globs
= uentry_getGlobs (e
);
1828 globSet_clear (gc
.globs_used
);
1829 gc
.mods
= uentry_getMods (e
);
1831 usymtab_enterFunctionScope (e
);
1832 sRef_enterFunctionScope ();
1835 bool context_inOldStyleScope(void)
1837 return (gc
.kind
== CX_OLDSTYLESCOPE
);
1841 context_enterOldStyleScope (void)
1843 gc
.kind
= CX_OLDSTYLESCOPE
;
1844 DPRINTF (("Enter old style scope!"));
1845 usymtab_enterFunctionScope (uentry_undefined
);
1849 context_completeOldStyleFunction (uentry e
)
1851 llassert (gc
.kind
== CX_OLDSTYLESCOPE
);
1853 gc
.kind
= CX_FUNCTION
;
1856 DPRINTF (("Enter function: %s", uentry_unparse (e
)));
1858 if (uentry_hasAccessType (e
))
1860 gc
.acct
= typeIdSet_subtract (typeIdSet_union (gc
.facct
, uentry_accessType (e
)),
1868 DPRINTF (("Enter function: %s / %s", uentry_unparse (e
),
1869 typeIdSet_unparse (gc
.acct
)));
1871 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1873 if (!globSet_isEmpty (uentry_getGlobs (e
)))
1875 llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
1876 fileloc_unparse (g_currentloc
), uentry_unparse (e
)));
1879 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1881 gc
.globs
= uentry_getGlobs (e
);
1882 globSet_clear (gc
.globs_used
);
1884 gc
.mods
= uentry_getMods (e
);
1886 if (!sRefSet_isEmpty (gc
.mods
))
1888 llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
1889 fileloc_unparse (g_currentloc
), uentry_unparse (e
)));
1892 sRef_enterFunctionScope ();
1895 static bool context_checkStrictGlobals (void)
1897 return (context_getFlag (FLG_CHECKSTRICTGLOBALS
));
1900 static bool context_hasGlobs (void)
1902 if (context_inFunctionLike ())
1904 return (uentry_hasGlobs (gc
.cont
.fcn
));
1912 static bool context_checkCheckedGlobals (void)
1914 return (context_getFlag (FLG_GLOBALS
)
1915 && (context_getFlag (FLG_GLOBUNSPEC
)
1916 || context_hasGlobs ()));
1919 static bool context_checkUnknownGlobals (void)
1921 /* should be uentry_hasGlobs ? */
1923 return (context_getFlag (FLG_ALLGLOBALS
)
1924 && (context_getFlag (FLG_GLOBUNSPEC
)
1925 || context_hasGlobs ()));
1928 static bool context_checkUncheckedGlobals (void)
1934 context_checkExport (uentry e
)
1936 if (!gc
.anyExports
) return FALSE
;
1938 if (uentry_isFunction (e
)
1939 || (uentry_isVariable (e
) && ctype_isFunction (uentry_getType (e
))))
1941 return context_maybeSet (FLG_EXPORTFCN
);
1943 else if (uentry_isExpandedMacro (e
))
1945 return context_maybeSet (FLG_EXPORTMACRO
);
1947 else if (uentry_isVariable (e
))
1949 return context_maybeSet (FLG_EXPORTVAR
);
1951 else if (uentry_isEitherConstant (e
))
1953 return context_maybeSet (FLG_EXPORTCONST
);
1955 else if (uentry_isIter (e
) || uentry_isEndIter (e
))
1957 return context_maybeSet (FLG_EXPORTITER
);
1959 else if (uentry_isDatatype (e
))
1961 return context_maybeSet (FLG_EXPORTTYPE
);
1970 context_checkGlobUse (uentry glob
)
1973 if (uentry_isCheckedStrict (glob
))
1975 return context_checkStrictGlobals ();
1977 else if (uentry_isChecked (glob
))
1979 return context_checkCheckedGlobals ();
1981 else if (uentry_isCheckedUnknown (glob
) || uentry_isCheckMod (glob
))
1983 return context_checkUnknownGlobals ();
1987 llassert (uentry_isUnchecked (glob
));
1989 return context_checkUncheckedGlobals ();
1994 context_checkAliasGlob (uentry glob
)
1996 if (uentry_isCheckedStrict (glob
))
1998 return gc
.flags
[FLG_CHECKSTRICTGLOBALIAS
];
2000 else if (uentry_isChecked (glob
))
2002 return gc
.flags
[FLG_CHECKEDGLOBALIAS
];
2004 else if (uentry_isCheckMod (glob
))
2006 return gc
.flags
[FLG_CHECKMODGLOBALIAS
];
2010 llassert (uentry_isUnchecked (glob
) || uentry_isCheckedUnknown (glob
));
2012 return gc
.flags
[FLG_UNCHECKEDGLOBALIAS
];
2016 bool context_checkInternalUse (void)
2018 if (context_hasGlobs ())
2020 return (gc
.flags
[FLG_INTERNALGLOBS
]);
2024 return (gc
.flags
[FLG_INTERNALGLOBSNOGLOBS
]);
2029 context_checkGlobMod (sRef el
)
2031 uentry ue
= sRef_getUentry (el
);
2033 /* no: llassert (sRef_isFileOrGlobalScope (el)); also check local statics */
2035 if (uentry_isCheckedModify (ue
)
2036 || (!uentry_isUnchecked (ue
) && (gc
.flags
[FLG_ALLGLOBALS
])))
2038 if (context_hasMods ())
2040 return (gc
.flags
[FLG_MODGLOBS
]);
2044 if (uentry_isCheckedStrict (ue
))
2046 return (gc
.flags
[FLG_MODGLOBSUNSPEC
]);
2050 return (gc
.flags
[FLG_MODSTRICTGLOBSUNSPEC
]);
2056 if (context_hasMods ())
2058 return (gc
.flags
[FLG_MODGLOBSUNCHECKED
]);
2068 context_usedGlobal (/*@exposed@*/ sRef el
)
2070 if (!globSet_member (gc
.globs_used
, el
))
2073 ** The first time a global is used in a function, we need
2074 ** to clear the derived sRefs, since they were set for the
2075 ** previous function.
2078 sRef_clearDerived (el
);
2079 gc
.globs_used
= globSet_insert (gc
.globs_used
, el
);
2083 /*@observer@*/ sRefSet
2084 context_modList (void)
2090 context_globAccess (sRef s
)
2092 llassert (sRef_isFileOrGlobalScope (s
) || sRef_isKindSpecial (s
));
2093 return (globSet_member (gc
.globs
, s
));
2097 context_hasAccess (typeId t
)
2099 if (context_inFunctionLike ())
2101 DPRINTF (("Access %d / %s",
2102 t
, typeIdSet_unparse (gc
.acct
)));
2103 return (typeIdSet_member (gc
.acct
, t
));
2107 return (context_hasFileAccess (t
));
2112 context_hasFileAccess (typeId t
)
2114 return (typeIdSet_member (gc
.facct
, t
));
2117 static /*@only@*/ cstring
2118 context_unparseAccess (void)
2120 return (message ("%q / %q", typeIdSet_unparse (gc
.acct
),
2121 typeIdSet_unparse (gc
.facct
)));
2125 context_unparseClauses (void)
2127 return (clauseStack_unparse (gc
.clauses
));
2131 context_couldHaveAccess (typeId t
)
2133 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
|| gc
.kind
== CX_UNKNOWNMACRO
)
2135 return (typeIdSet_member (gc
.acct
, t
));
2139 return (typeIdSet_member (gc
.facct
, t
));
2144 context_getRetType (void)
2146 ctype f
= ctype_undefined
;
2148 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
)
2150 f
= uentry_getType (gc
.cont
.fcn
);
2152 else if (gc
.kind
== CX_UNKNOWNMACRO
)
2154 return ctype_unknown
;
2158 llcontbuglit ("context_getRetType: not in a function context");
2159 return ctype_unknown
;
2162 if (!ctype_isFunction (f
))
2164 if (ctype_isKnown (f
))
2166 llbuglit ("context_getRetType: not a function");
2169 return ctype_unknown
;
2171 return (ctype_getReturnType (f
));
2175 context_hasMods (void)
2177 if (context_inFunctionLike ())
2179 return (uentry_hasMods (gc
.cont
.fcn
));
2188 context_exitAllClauses (void)
2190 while (!clauseStack_isEmpty (gc
.clauses
))
2192 clause el
= clauseStack_top (gc
.clauses
);
2195 if (clause_isNone (el
))
2197 usymtab_quietExitScope (g_currentloc
);
2198 clauseStack_pop (gc
.clauses
);
2202 context_exitClausePlain ();
2206 clauseStack_clear (gc
.clauses
);
2207 gc
.inclause
= NOCLAUSE
;
2211 context_exitAllClausesQuiet (void)
2213 while (!clauseStack_isEmpty (gc
.clauses
))
2215 clause el
= clauseStack_top (gc
.clauses
);
2218 usymtab_quietExitScope (g_currentloc
);
2219 clauseStack_pop (gc
.clauses
);
2222 clauseStack_clear (gc
.clauses
);
2223 gc
.inclause
= NOCLAUSE
;
2227 void context_exitClauseSimp (void)
2230 context_setJustPopped ();
2231 clauseStack_pop (gc
.clauses
);
2232 gc
.inclause
= topClause (gc
.clauses
);
2236 void context_exitCaseClause (void)
2238 context_setJustPopped ();
2239 usymtab_popCaseBranch ();
2240 clauseStack_pop (gc
.clauses
);
2241 gc
.inclause
= topClause (gc
.clauses
);
2245 void context_exitClauseAux (exprNode pred
, exprNode tbranch
)
2247 context_setJustPopped ();
2248 usymtab_popTrueBranch (pred
, tbranch
, gc
.inclause
); /* evans 2003-02-02?: was makeAlt */
2249 clauseStack_pop (gc
.clauses
);
2250 gc
.inclause
= topClause (gc
.clauses
);
2253 void context_exitTrueClause (exprNode pred
, exprNode tbranch
)
2255 DPRINTF (("Exit true clause: %s", exprNode_unparse (tbranch
)));
2257 if (gc
.inclause
!= TRUECLAUSE
)
2259 llparseerror (cstring_makeLiteral
2260 ("Likely parse error. Conditional clauses are inconsistent."));
2264 context_setJustPopped ();
2265 usymtab_popTrueBranch (pred
, tbranch
, TRUECLAUSE
);
2266 clauseStack_pop (gc
.clauses
);
2267 gc
.inclause
= topClause (gc
.clauses
);
2270 void context_exitIterClause (exprNode body
)
2272 llassert (gc
.inclause
== ITERCLAUSE
);
2274 context_setJustPopped ();
2276 if (context_getFlag (FLG_ITERLOOPEXEC
))
2278 usymtab_popTrueExecBranch (exprNode_undefined
, body
, ITERCLAUSE
);
2282 usymtab_popTrueBranch (exprNode_undefined
, body
, ITERCLAUSE
);
2285 clauseStack_pop (gc
.clauses
);
2286 gc
.inclause
= topClause (gc
.clauses
);
2289 static void context_popCase (void) {
2291 ** If we are exiting an outer clause, sometimes still in a switch case.
2305 DPRINTF (("Popping case clause: %s",
2306 clauseStack_unparse (gc
.clauses
)));
2308 if (gc
.inclause
== CASECLAUSE
) {
2309 context_exitCaseClause ();
2313 void context_exitWhileClause (exprNode pred
, exprNode body
)
2315 guardSet invGuards
= guardSet_invert (exprNode_getGuards (pred
));
2319 if (gc
.inclause
!= WHILECLAUSE
) {
2320 DPRINTF (("Clause: %s / %s", clause_unparse (gc
.inclause
),
2321 clauseStack_unparse (gc
.clauses
)));
2324 llassert (gc
.inclause
== WHILECLAUSE
);
2326 context_setJustPopped ();
2330 ** predicate must be false after while loop (unless there are breaks)
2333 if (context_getFlag (FLG_WHILELOOPEXEC
))
2335 usymtab_popTrueExecBranch (pred
, body
, WHILECLAUSE
);
2339 usymtab_popTrueBranch (pred
, body
, WHILECLAUSE
);
2343 usymtab_addGuards (invGuards
);
2344 guardSet_free (invGuards
);
2346 clauseStack_pop (gc
.clauses
);
2347 gc
.inclause
= topClause (gc
.clauses
);
2350 void context_exitDoWhileClause (exprNode pred
)
2352 guardSet invGuards
= guardSet_invert (exprNode_getGuards (pred
));
2354 if (gc
.inclause
== CASECLAUSE
) {
2355 /* handle Duff's device */
2356 clauseStack_pop (gc
.clauses
);
2357 gc
.inclause
= topClause (gc
.clauses
);
2360 llassert (gc
.inclause
== DOWHILECLAUSE
);
2362 context_setJustPopped ();
2365 usymtab_addGuards (invGuards
);
2366 guardSet_free (invGuards
);
2368 clauseStack_pop (gc
.clauses
);
2369 gc
.inclause
= topClause (gc
.clauses
);
2372 void context_exitForClause (exprNode forPred
, exprNode body
)
2374 guardSet invGuards
= guardSet_invert (exprNode_getForGuards (forPred
));
2376 llassert (gc
.inclause
== FORCLAUSE
);
2377 context_setJustPopped ();
2379 DPRINTF (("Exit for: %s / %s", exprNode_unparse (forPred
), exprNode_unparse (body
)));
2382 ** Predicate must be false after for loop (unless there are breaks)
2385 if (context_getFlag (FLG_FORLOOPEXEC
))
2387 DPRINTF (("Here: for loop exec"));
2388 usymtab_popTrueExecBranch (forPred
, body
, FORCLAUSE
);
2392 if (context_getFlag (FLG_OBVIOUSLOOPEXEC
)
2393 && exprNode_loopMustExec (forPred
))
2395 DPRINTF (("Here: loop must exec"));
2396 usymtab_popTrueExecBranch (forPred
, body
, FORCLAUSE
);
2400 DPRINTF (("Pop true branch:"));
2401 usymtab_popTrueBranch (forPred
, body
, FORCLAUSE
);
2405 usymtab_addGuards (invGuards
);
2406 guardSet_free (invGuards
);
2407 clauseStack_pop (gc
.clauses
);
2408 gc
.inclause
= topClause (gc
.clauses
);
2411 static void context_exitClausePlain (void)
2413 llassert (gc
.inclause
!= NOCLAUSE
);
2415 if (gc
.inclause
== FALSECLAUSE
)
2417 context_exitClause (exprNode_undefined
, exprNode_undefined
, exprNode_undefined
);
2421 context_exitClauseAux (exprNode_undefined
, exprNode_undefined
);
2425 void context_exitClause (exprNode pred
, exprNode tbranch
, exprNode fbranch
)
2427 context_setJustPopped ();
2429 if (gc
.inclause
== FALSECLAUSE
)
2431 usymtab_popBranches (pred
, tbranch
, fbranch
, FALSE
, FALSECLAUSE
);
2433 llassert (clauseStack_top (gc
.clauses
) == FALSECLAUSE
);
2435 clauseStack_pop (gc
.clauses
);
2436 gc
.inclause
= topClause (gc
.clauses
);
2440 context_exitTrueClause (pred
, tbranch
);
2445 context_returnFunction (void)
2447 usymtab_checkFinalScope (TRUE
);
2451 context_exitFunction (void)
2453 DPRINTF (("Exit function: %s", context_unparse ()));
2455 if (!context_inFunction () && !context_inMacroConstant ()
2456 && !context_inUnknownMacro ()
2457 && !context_inIterDef () && !context_inIterEnd ())
2460 ** not a bug because of parse errors
2467 if (context_inMacro () && usymtab_inFunctionScope ())
2469 usymtab_exitScope (exprNode_undefined
);
2472 if (uentry_hasGlobs (gc
.cont
.fcn
))
2474 exprChecks_checkUsedGlobs (gc
.globs
, gc
.globs_used
);
2478 if (uentry_hasMods (gc
.cont
.fcn
))
2480 if (context_getFlag (FLG_MUSTMOD
))
2482 exprNode_checkAllMods (gc
.mods
, gc
.cont
.fcn
);
2486 DPRINTF (("Exit function: %s", uentry_unparse (gc
.cont
.fcn
)));
2489 ** clear file static modifies
2492 /* do this first to get unused error messages */
2494 usymtab_exitScope (exprNode_undefined
);
2495 sRef_exitFunctionScope ();
2497 gc
.showfunction
= FALSE
;
2498 gc
.kind
= CX_GLOBAL
;
2499 gc
.cont
.glob
= TRUE
;
2501 gc
.globs
= globSet_new ();
2502 globSet_clear (gc
.globs_used
);
2503 gc
.mods
= sRefSet_new ();
2506 llassert (clauseStack_isEmpty (gc
.clauses
));
2507 llassert (gc
.inclause
== NOCLAUSE
);
2508 DPRINTF (("After exit function: %s", context_unparse ()));
2512 context_quietExitFunction (void)
2514 while (gc
.kind
== CX_INNER
)
2516 context_exitInnerPlain ();
2519 if (!context_inFunction () && !context_inMacroConstant () && !context_inUnknownMacro ()
2520 && !context_inIterDef () && !context_inIterEnd ())
2525 usymtab_quietExitScope (g_currentloc
);
2527 gc
.showfunction
= FALSE
;
2528 gc
.kind
= CX_GLOBAL
;
2529 gc
.cont
.glob
= TRUE
;
2531 gc
.globs
= globSet_new ();
2532 globSet_clear (gc
.globs_used
);
2533 gc
.mods
= sRefSet_new ();
2535 sRef_exitFunctionScope ();
2539 /*@observer@*/ uentryList
2540 context_getParams (void)
2542 if (context_inFunctionLike ())
2544 return (uentry_getParams (gc
.cont
.fcn
));
2548 llcontbug (message ("context_getParams: not in function: %q", context_unparse ()));
2549 return uentryList_undefined
;
2553 /*@observer@*/ globSet
2554 context_getUsedGlobs (void)
2556 llassert (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
2557 || gc
.kind
== CX_UNKNOWNMACRO
|| gc
.kind
== CX_ITERDEF
);
2559 return (gc
.globs_used
);
2563 context_moduleName (void)
2565 return (fileloc_getBase (g_currentloc
));
2568 /*@observer@*/ globSet
2569 context_getGlobs (void)
2571 llassert (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
2572 || gc
.kind
== CX_UNKNOWNMACRO
|| gc
.kind
== CX_ITERDEF
);
2578 context_addBoolAccess (void)
2580 cstring bname
= context_getString (FLG_BOOLTYPE
);
2581 typeIdSet boolt
= typeIdSet_single (usymtab_getTypeId (bname
));
2583 addModuleAccess (cstring_copy (bname
), boolt
);
2585 /* for sys/types (perhaps, this is bogus!) */
2586 addModuleAccess (cstring_makeLiteral ("types"), boolt
);
2591 context_canAccessBool (void)
2598 static typeId boolType = typeId_invalid;
2600 if (typeId_isInvalid (boolType))
2602 boolType = usymtab_getTypeId (context_getBoolName ());
2605 if (typeId_isInvalid (boolType)) {
2608 return (typeIdSet_member (gc.acct, boolType));
2613 /* evs 2000-07-25: old version - replaced */
2616 context_boolImplementationType (void) {
2617 /* For now, this is bogus! */
2622 context_canAccessBool (void)
2624 static typeId boolType
= typeId_invalid
;
2626 if (typeId_isInvalid (boolType
))
2628 boolType
= usymtab_getTypeId (context_getBoolName ());
2631 if (!typeId_isInvalid (boolType
))
2633 return context_hasAccess (boolType
);
2644 context_setMessageAnnote (/*@only@*/ cstring s
)
2646 llassert (cstring_isUndefined (gc
.msgAnnote
));
2651 context_hasMessageAnnote (void)
2653 return (cstring_isDefined (gc
.msgAnnote
));
2657 context_clearMessageAnnote (void)
2659 if (cstring_isDefined (gc
.msgAnnote
))
2661 cstring_free (gc
.msgAnnote
);
2662 gc
.msgAnnote
= cstring_undefined
;
2667 context_getMessageAnnote (void)
2669 cstring st
= gc
.msgAnnote
;
2671 gc
.msgAnnote
= cstring_undefined
;
2676 context_setAliasAnnote (/*@observer@*/ sRef s
, /*@observer@*/ sRef t
)
2678 llassert (sRef_isInvalid (gc
.aliasAnnote
));
2679 llassert (!sRef_sameName (s
, t
));
2681 gc
.aliasAnnoteAls
= t
;
2685 context_hasAliasAnnote (void)
2687 return (sRef_isValid (gc
.aliasAnnote
));
2691 context_clearAliasAnnote (void)
2693 gc
.aliasAnnote
= sRef_undefined
;
2697 context_getAliasAnnote (void)
2699 sRef ret
= gc
.aliasAnnote
;
2700 sRef als
= gc
.aliasAnnoteAls
;
2702 llassert (sRef_isValid (ret
) && sRef_isValid (als
));
2704 gc
.aliasAnnote
= sRef_undefined
;
2705 return (message ("%q aliases %q", sRef_unparse (als
), sRef_unparse (ret
)));
2709 context_recordFileModifies (sRefSet mods
)
2711 gc
.modrecs
= sRefSetList_add (gc
.modrecs
, mods
);
2715 context_recordFileGlobals (globSet mods
)
2717 DPRINTF (("Recording file globals: %s", globSet_unparse (mods
)));
2718 /*@access globSet@*/ context_recordFileModifies (mods
); /*@noaccess globSet@*/
2722 context_setCommentMarkerChar (char c
)
2724 llassert (c
!= '\0');
2726 context_setValue (FLG_COMMENTCHAR
, (int) c
);
2730 context_getCommentMarkerChar (void)
2732 return ((char) context_getValue (FLG_COMMENTCHAR
));
2736 context_setValue (flagcode flag
, int val
)
2738 int index
= flagcode_valueIndex (flag
);
2740 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2748 llerror_flagWarning (message ("Value for %s must be a positive "
2749 "number (given %d)",
2750 flagcode_unparse (flag
), val
));
2753 if (flag
== FLG_LINELEN
&& val
< MINLINELEN
)
2755 llerror_flagWarning (message ("Value for %s must be at least %d (given %d)",
2756 flagcode_unparse (flag
),
2762 case FLG_INCLUDENEST
:
2763 case FLG_CONTROLNESTDEPTH
:
2764 case FLG_STRINGLITERALLEN
:
2765 case FLG_NUMSTRUCTFIELDS
:
2766 case FLG_NUMENUMMEMBERS
:
2767 case FLG_INDENTSPACES
:
2770 llerror_flagWarning (message ("Value for %s must be a non-negative "
2771 "number (given %d)",
2772 flagcode_unparse (flag
), val
));
2781 DPRINTF (("Set value [%s] %d = %d", flagcode_unparse (flag
), index
, val
));
2782 gc
.values
[index
] = val
;
2786 context_setValueAndFlag (flagcode flag
, int val
)
2788 gc
.flags
[flag
] = TRUE
;
2789 context_setValue (flag
, val
);
2793 context_getValue (flagcode flag
)
2795 int index
= flagcode_valueIndex (flag
);
2797 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2798 DPRINTF (("Get value [%s] %d = %d", flagcode_unparse (flag
), index
, gc
.values
[index
]));
2799 return (gc
.values
[index
]);
2804 context_getCounter (flagcode flag
)
2806 int index
= flagcode_valueIndex (flag
);
2808 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2809 return (gc
.counters
[index
]);
2813 context_incCounter (flagcode flag
)
2815 int index
= flagcode_valueIndex (flag
);
2817 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2819 gc
.counters
[index
]++;
2823 context_decCounter (flagcode flag
)
2825 int index
= flagcode_valueIndex (flag
);
2827 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2828 gc
.counters
[index
]--;
2830 # endif /* DEADCODE */
2832 bool context_showFunction (void)
2834 return (gc
.showfunction
);
2838 context_setString (flagcode flag
, cstring val
)
2840 int index
= flagcode_stringIndex (flag
);
2842 llassert (index
>= 0 && index
<= NUMSTRINGFLAGS
);
2844 DPRINTF (("set string: %s", flagcode_unparse (flag
)));
2848 case FLG_MESSAGESTREAM
:
2849 case FLG_WARNINGSTREAM
:
2850 case FLG_ERRORSTREAM
:
2852 if (cstring_isDefined (val
))
2856 if (osd_fileExists (val
))
2858 if (context_getFlag (FLG_STREAMOVERWRITE
))
2860 llfatalerror (message
2861 ("Output stream file %s would overwrite existing file. "
2862 "Use -streamoverwrite if you want to allow this.",
2867 fstream
= fopen (cstring_toCharsSafe (val
), "w");
2869 if (fstream
== NULL
)
2871 llfatalerror (message ("Unable to open output stream file %s for writing",
2876 ** This ensures fstream will be closed on exit.
2879 fileTable_addStreamFile (gc
.ftab
, fstream
, cstring_copy (val
));
2883 case FLG_MESSAGESTREAM
:
2884 g_messagestream
= fstream
;
2885 /*@innerbreak@*/ break;
2886 case FLG_WARNINGSTREAM
:
2887 g_warningstream
= fstream
;
2888 /*@innerbreak@*/ break;
2889 case FLG_ERRORSTREAM
:
2890 g_errorstream
= fstream
;
2891 /*@innerbreak@*/ break;
2894 /*@-statetransfer@*/
2895 } /*@=statetransfer@*/ /* fstream not closed, but will be on exit */
2898 case FLG_SYSTEMDIRS
:
2900 llassert (cstring_isDefined (val
));
2902 if (cstring_firstChar (val
) == '\"')
2905 cstring tval
= cstring_copy (cstring_suffix (val
, 1));
2907 if (cstring_lastChar (tval
) != '\"')
2909 int n
= size_toInt (cstring_length (tval
) - 1);
2911 while (isspace ((int) cstring_getChar (tval
, size_fromInt (n
))))
2916 if (cstring_getChar (tval
, size_fromInt (n
)) != '\"')
2919 (message ("Setting -systemdirs to string with unmatching quotes: %s", val
));
2923 cstring otval
= tval
;
2924 tval
= cstring_prefix (tval
, size_fromInt (n
));
2925 cstring_free (otval
);
2929 val
= cstring_copy (cstring_clip (tval
, cstring_length (tval
) - 1));
2930 DPRINTF (("val = %s", val
));
2931 cstring_free (tval
);
2932 cstring_free (oval
);
2939 llassert (cstring_isDefined (val
));
2941 if (cstring_length (val
) == 0)
2944 val
= message (".%s", cstring_makeLiteralTemp (CONNECTSTR
));
2946 else if (cstring_lastChar (val
) != CONNECTCHAR
)
2948 val
= cstring_appendChar (val
, CONNECTCHAR
);
2958 ; /* Okay not handle everything in this switch */
2961 } /* evans 2002-03-24: splintme reports a spurious (I think) warning here...need to look into it */
2964 if (cstring_length (val
) >= 1
2965 && cstring_firstChar (val
) == '\"')
2967 llerror_flagWarning (message
2968 ("Setting %s to string beginning with \". You probably "
2969 "don't meant to have the \"'s.",
2970 flagcode_unparse (flag
)));
2973 gc
.strings
[index
] = val
;
2976 static /*@exposed@*/ cstring
2977 context_exposeString (flagcode flag
)
2979 int index
= flagcode_stringIndex (flag
);
2981 llassert (index
>= 0 && index
<= NUMSTRINGFLAGS
);
2982 return (gc
.strings
[index
]);
2986 context_getString (flagcode flag
)
2988 return (context_exposeString (flag
));
2992 context_resetErrors (void)
2998 context_recordBug (void)
3004 context_numBugs (void)
3009 void context_initMod (void)
3010 /*@globals undef gc; @*/
3012 gc
.kind
= CX_GLOBAL
;
3014 gc
.savekind
= CX_ERROR
;
3015 gc
.savecont
.glob
= FALSE
;
3017 gc
.instandardlib
= FALSE
;
3021 gc
.linesprocessed
= 0;
3022 gc
.speclinesprocessed
= 0;
3023 gc
.insuppressregion
= FALSE
;
3024 gc
.macroMissingParams
= FALSE
;
3025 gc
.preprocessing
= FALSE
;
3026 gc
.incommandline
= FALSE
;
3027 gc
.mc
= macrocache_create ();
3029 gc
.maxmods
= DEFAULTMAXMODS
;
3030 gc
.moduleaccess
= (maccesst
*) dmalloc (sizeof (*gc
.moduleaccess
) * (gc
.maxmods
));
3032 gc
.library
= FLG_ANSILIB
;
3034 gc
.locstack
= filelocStack_new ();
3035 gc
.modrecs
= sRefSetList_undefined
;
3036 gc
.anyExports
= FALSE
;
3038 gc
.ftab
= fileTable_create ();
3039 gc
.msgLog
= messageLog_new ();
3040 gc
.inimport
= FALSE
;
3041 gc
.inDerivedFile
= FALSE
;
3042 gc
.inheader
= FALSE
;
3043 gc
.markers
= flagMarkerList_new ();
3044 gc
.cont
.glob
= TRUE
;
3045 gc
.showfunction
= FALSE
;
3046 gc
.msgAnnote
= cstring_undefined
;
3047 gc
.aliasAnnote
= sRef_undefined
;
3048 gc
.aliasAnnoteAls
= sRef_undefined
;
3049 gc
.boolType
= ctype_bool
;
3050 gc
.mods
= sRefSet_new ();
3052 gc
.saveloc
= fileloc_undefined
;
3054 gc
.inmacrocache
= FALSE
;
3055 gc
.inclause
= NOCLAUSE
;
3056 gc
.clauses
= clauseStack_new ();
3057 gc
.globs
= globSet_new ();
3058 gc
.nacct
= typeIdSet_emptySet ();
3059 gc
.acct
= typeIdSet_emptySet ();
3060 gc
.facct
= typeIdSet_emptySet ();
3061 gc
.savedFlags
= FALSE
;
3062 gc
.pushloc
= fileloc_undefined
;
3063 gc
.protectVars
= FALSE
;
3064 gc
.justpopped
= FALSE
;
3065 gc
.isNullGuarded
= NO
;
3066 gc
.globs_used
= globSet_undefined
;
3070 gc
.setGlobally
[code
] = FALSE
;
3071 gc
.setLocally
[code
] = FALSE
;
3076 context_resetAllFlags ();
3078 assertSet (gc
.flags
); /* Can't use global in defines */
3079 assertSet (gc
.saveflags
);
3080 assertSet (gc
.values
);
3081 assertSet (gc
.strings
);
3083 conext_resetAllCounters ();
3084 assertSet (gc
.counters
);
3086 context_setMode (DEFAULT_MODE
);
3088 gc
.stateTable
= metaStateTable_create ();
3089 gc
.annotTable
= annotationTable_create ();
3091 gc
.inFunctionHeader
= FALSE
;
3093 DPRINTF (("Annotations: \n%s",
3094 cstring_toCharsSafe (annotationTable_unparse (gc
.annotTable
))));
3095 DPRINTF (("State: \n%s",
3096 cstring_toCharsSafe (metaStateTable_unparse (gc
.stateTable
))));
3101 context_typeofZero (void)
3103 ctype ct
= ctype_int
;
3105 if (context_getFlag (FLG_ZEROPTR
))
3107 ct
= ctype_makeConj (ct
, ctype_voidPointer
);
3110 if (context_getFlag (FLG_ZEROBOOL
)) {
3111 ct
= ctype_makeConj (ct
, ctype_bool
);
3118 context_typeofOne (void)
3120 ctype ct
= ctype_int
;
3122 /* 1 is on longer a bool (was before 2.4)
3123 if (!context_getFlag (FLG_ABSTRACTBOOL))
3125 ct = ctype_makeConj (ct, ctype_bool);
3133 context_unparse (void)
3140 s
= message ("LCL File: %q", fileloc_unparse (g_currentloc
));
3143 s
= message ("LCL Lib File: %q", fileloc_unparse (g_currentloc
));
3146 s
= message ("Global Context:%q", fileloc_unparse (g_currentloc
));
3149 s
= message ("Inner Context [%d] : %q",
3151 fileloc_unparse (g_currentloc
));
3154 s
= message ("Function %q :%q \n\taccess %q\n\tmodifies %q",
3155 uentry_unparse (gc
.cont
.fcn
),
3156 fileloc_unparse (g_currentloc
),
3157 typeIdSet_unparse (gc
.acct
),
3158 sRefSet_unparse (gc
.mods
));
3161 s
= message ("Function Macro %q", uentry_unparse (gc
.cont
.fcn
));
3163 case CX_UNKNOWNMACRO
:
3164 s
= message ("Forward Specified Macro %q", uentry_unparse (gc
.cont
.fcn
));
3167 s
= message ("Constant Macro %q", uentry_unparse (gc
.cont
.fcn
));
3170 s
= message ("Iter definition %q", uentry_unparse (gc
.cont
.fcn
));
3173 s
= message ("Iter end %q", uentry_unparse (gc
.cont
.fcn
));
3175 case CX_FCNDECLARATION
:
3176 s
= message ("Function declaration %q", uentry_unparse (gc
.cont
.fcn
));
3179 s
= message ("Un-unparseable context: %d", (int) gc
.kind
);
3183 s
= message ("%q\naccess: %q", s
, context_unparseAccess ());
3188 context_currentFunctionType (void)
3190 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
)
3192 return (uentry_getType (gc
.cont
.fcn
));
3194 else if (gc
.kind
== CX_INNER
)
3196 llcontbuglit ("context_currentFunctionType: inner context");
3197 do { context_exitInnerPlain (); } while (gc
.kind
== CX_INNER
);
3198 return (context_currentFunctionType ());
3202 llcontbuglit ("context_currentFunctionType: not in function");
3203 return (ctype_undefined
);
3208 context_enterInnerContext (void)
3210 if (context_getFlag (FLG_GRAMMAR
))
3212 lldiagmsg (message ("Enter inner context: %q", context_unparse ()));
3215 if (gc
.kind
== CX_GLOBAL
)
3220 else if (gc
.kind
== CX_INNER
)
3229 usymtab_enterScope ();
3230 pushClause (NOCLAUSE
);
3234 context_exitInnerPlain (void) /*@modifies gc;@*/
3236 context_exitInner (exprNode_undefined
);
3240 context_exitInner (exprNode exp
)
3242 if (context_getFlag (FLG_GRAMMAR
))
3244 lldiagmsg (message ("Enter inner context: %q", context_unparse ()));
3247 llassertprint (gc
.inclause
== NOCLAUSE
|| gc
.inclause
== CASECLAUSE
,
3248 ("inclause = %s", clause_nameTaken (gc
.inclause
)));
3250 clauseStack_removeFirst (gc
.clauses
, NOCLAUSE
);
3251 gc
.inclause
= topClause (gc
.clauses
);
3253 if (gc
.kind
== CX_INNER
)
3255 if (--gc
.cont
.cdepth
== 0)
3257 gc
.kind
= CX_GLOBAL
;
3258 gc
.cont
.glob
= TRUE
;
3263 if (gc
.kind
== CX_GLOBAL
)
3265 llcontbuglit ("Attempt to exit global context");
3270 usymtab_exitScope (exp
);
3275 context_enterStructInnerContext (void)
3277 if (context_getFlag (FLG_GRAMMAR
))
3279 lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
3282 if (gc
.kind
== CX_GLOBAL
)
3287 else if (gc
.kind
== CX_INNER
)
3296 usymtab_enterScope ();
3298 if (context_getFlag (FLG_GRAMMAR
))
3300 lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
3305 context_exitStructInnerContext (void)
3307 if (context_getFlag (FLG_GRAMMAR
))
3309 lldiagmsg (message ("Exit struct inner context: %q [%d]", context_unparse (), gc
.cont
.cdepth
));
3312 if (gc
.kind
== CX_INNER
)
3314 if (gc
.cont
.cdepth
<= 0)
3316 llcontbuglit ("Attempt to exit inner context with no depth");
3317 gc
.kind
= CX_GLOBAL
;
3318 gc
.cont
.glob
= TRUE
;
3324 if (gc
.cont
.cdepth
== 0)
3326 gc
.kind
= CX_GLOBAL
;
3327 gc
.cont
.glob
= TRUE
;
3333 if (gc
.kind
== CX_GLOBAL
)
3335 llcontbuglit ("Attempt to exit global context");
3340 usymtab_exitScope (exprNode_undefined
);
3342 if (context_getFlag (FLG_GRAMMAR
))
3344 lldiagmsg (message ("After exit struct inner context: %q [%d]", context_unparse (), gc
.cont
.cdepth
));
3349 context_exitInnerSafe (void)
3351 if (context_getFlag (FLG_GRAMMAR
))
3353 lldiagmsg (message ("Exit inner safe: %q", context_unparse ()));
3356 if (gc
.kind
== CX_INNER
)
3358 if (--gc
.cont
.cdepth
<= 0)
3363 else if (gc
.kind
== CX_GLOBAL
)
3365 llcontbuglit ("Attempt to exit global context");
3370 if (usymtab_inDeepScope ())
3372 usymtab_exitScope (exprNode_undefined
);
3378 void setModuleAccess (void)
3380 gc
.facct
= typeIdSet_emptySet ();
3382 if (fileId_isValid (currentFile ()))
3384 cstring baseName
= fileloc_getBase (g_currentloc
);
3386 if (context_getFlag (FLG_ACCESSFILE
))
3388 if (usymtab_existsType (baseName
))
3390 gc
.facct
= typeIdSet_insert (gc
.facct
,
3391 usymtab_getTypeId (baseName
));
3399 if (context_getFlag (FLG_ACCESSMODULE
))
3403 for (i
= 0; i
< gc
.nmods
; i
++)
3405 if (cstring_equal (baseName
, gc
.moduleaccess
[i
].file
))
3407 gc
.facct
= typeIdSet_union (gc
.facct
, gc
.moduleaccess
[i
].daccess
);
3415 gc
.inheader
= fileId_isHeader (currentFile ());
3419 llcontbuglit ("Current file not defined\n");
3420 gc
.facct
= typeIdSet_emptySet ();
3422 gc
.inheader
= FALSE
;
3425 /* 17 Jan 1995: forgot to clear nacct */
3427 gc
.nacct
= typeIdSet_emptySet ();
3431 context_enterFileAux (void)
3437 context_enterFile (void)
3439 context_enterFileAux ();
3440 usymtab_enterFile ();
3444 context_enterMacroFile (void)
3446 context_enterFileAux ();
3450 context_inFunction (void)
3452 kcontext ck
= gc
.kind
;
3454 return ((ck
== CX_FUNCTION
) || (ck
== CX_MACROFCN
) || (ck
== CX_INNER
));
3458 context_inFunctionLike (void)
3460 return (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
3461 || gc
.kind
== CX_FCNDECLARATION
3462 || gc
.kind
== CX_UNKNOWNMACRO
|| gc
.kind
== CX_ITERDEF
);
3466 context_inRealFunction (void)
3468 kcontext ck
= gc
.kind
;
3470 return ((ck
== CX_FUNCTION
) || (ck
== CX_MACROFCN
));
3474 context_processAllMacros (void)
3476 usymtab_enterFile ();
3478 gc
.inmacrocache
= TRUE
;
3479 macrocache_processUndefinedElements (gc
.mc
);
3481 usymtab_exitFile ();
3483 gc
.inmacrocache
= FALSE
;
3484 macrocache_finalize ();
3488 ** this happens once at the end of each C file
3490 ** check each Macro that was defined in current file.c or current file.h
3495 context_processMacros (void)
3497 if (fileId_isValid (currentFile ()))
3500 cstring cbase
= fileLib_removePathFree (fileLib_removeAnyExtension (fileTable_fileName (currentFile ())));
3502 gc
.inmacrocache
= TRUE
;
3504 DPRINTF (("Processing macros: %s", cbase
));
3505 lastfl
= macrocache_processFileElements (gc
.mc
, cbase
);
3506 DPRINTF (("Processing macros: %s", fileloc_unparse (lastfl
)));
3508 cstring_free (cbase
);
3510 if (fileloc_isDefined (lastfl
))
3512 g_currentloc
= fileloc_update (g_currentloc
, lastfl
);
3516 gc
.inmacrocache
= FALSE
;
3521 context_processingMacros (void)
3523 return (gc
.inmacrocache
);
3527 context_exitCFile (void)
3529 if (gc
.kind
!= CX_GLOBAL
)
3532 (cstring_makeLiteral ("File ended outside global scope"));
3535 if (gc
.insuppressregion
)
3537 /* gack...don't reverse the order of these lines! ;-> */
3538 gc
.insuppressregion
= FALSE
;
3539 llerrorlit (FLG_SYNTAX
,
3540 "File ended in ignore errors region, "
3541 "possible missing /*@end*/");
3544 /* fix up parse errors */
3546 while (!usymtab_inFileScope ())
3548 usymtab_quietExitScope (g_currentloc
);
3552 ** Clear the file-specific modifies information.
3555 sRefSetList_elements (gc
.modrecs
, mods
)
3557 sRefSet_clearStatics (mods
);
3558 } end_sRefSetList_elements
;
3560 sRefSetList_clear (gc
.modrecs
);
3562 context_processMacros ();
3565 usymtab_exitFile ();
3567 gc
.inDerivedFile
= FALSE
;
3568 filelocStack_clear (gc
.locstack
);
3570 gc
.nacct
= typeIdSet_emptySet (); /* empty noaccess */
3572 gc
.cont
.glob
= TRUE
;
3576 context_restoreFlagSettings ();
3577 gc
.savedFlags
= FALSE
;
3581 DPRINTF (("After exiting file: "));
3582 usymtab_printAll ();
3587 context_exitMacroCache (void)
3589 if (gc
.kind
!= CX_GLOBAL
)
3591 if (context_inMacro ())
3592 /* this is okay, file could end without newline in macro */
3594 DPRINTF (("Still in macro: %s",
3595 context_unparse ()));
3596 context_exitFunction ();
3600 llcontbug (message ("context_exitMacroCache: outside global scope: %q",
3601 context_unparse ()));
3602 gc
.kind
= CX_GLOBAL
;
3607 ** no longer valid here
3608 ** if (gc.insuppressregion)
3610 ** gc.insuppressregion = FALSE;
3611 ** llerror ("File ended in ignore errors region, possible missing @");
3615 gc
.cont
.glob
= TRUE
;
3619 context_saveLocation (void)
3621 /* was llassert (fileloc_isUndefined (gc.saveloc)) */
3622 fileloc_free (gc
.saveloc
);
3623 gc
.saveloc
= fileloc_copy (g_currentloc
);
3627 context_getSaveLocation (void)
3629 fileloc fl
= gc
.saveloc
;
3630 gc
.saveloc
= fileloc_undefined
;
3634 /*@observer@*/ cstring
3635 context_inFunctionName (void)
3637 if (gc
.kind
== CX_FUNCTION
3638 || gc
.kind
== CX_MACROFCN
|| gc
.kind
== CX_UNKNOWNMACRO
3639 || gc
.kind
== CX_MACROCONST
3640 || gc
.kind
== CX_ITERDEF
|| gc
.kind
== CX_ITEREND
)
3642 return (uentry_rawName (gc
.cont
.fcn
));
3646 llcontbuglit ("context_inFunctionName: not in function");
3647 return (cstring_undefined
);
3652 context_userSetFlag (flagcode f
, bool b
)
3654 DPRINTF (("set flag: %s / %s",
3655 flagcode_unparse (f
),
3656 bool_unparse (context_getFlag (f
))));
3658 if (f
== FLG_NEVERINCLUDE
&& b
)
3660 if (gc
.flags
[FLG_EXPORTHEADER
])
3663 (cstring_makeLiteral
3664 ("Setting +neverinclude after +exportheader. "
3665 "Turning off exportheader, since headers are not checked "
3666 "when +neverinclude is used."));
3668 gc
.flags
[FLG_EXPORTHEADER
] = FALSE
;
3673 if (f
== FLG_EXPORTHEADER
&& b
)
3675 if (gc
.flags
[FLG_NEVERINCLUDE
])
3678 (cstring_makeLiteral
3679 ("Setting +exportheader after +neverinclude. "
3680 "Not setting exportheader, since headers are not checked "
3681 "when +neverinclude is used."));
3682 gc
.flags
[FLG_EXPORTHEADER
] = FALSE
;
3688 if (context_getFlag (FLG_WARNFLAGS
) && f
!= FLG_NOF
&& f
!= FLG_OPTF
)
3690 bool lastsetting
= context_getFlag (f
);
3692 if (bool_equal (lastsetting
, b
)
3693 && !flagcode_isSpecialFlag (f
)
3694 && !flagcode_isIdemFlag (f
)
3695 && !flagcode_hasArgument (f
))
3698 (message ("Setting %s%s redundant with current value",
3699 cstring_makeLiteralTemp (b
? "+" : "-"),
3700 flagcode_unparse (f
)));
3704 if (flagcode_isWarnUseFlag (f
) && b
)
3706 if (!context_getFlag (FLG_WARNUSE
))
3709 (message ("Flag +%s is canceled by -warnuse",
3710 flagcode_unparse (f
)));
3715 if (flagcode_isLibraryFlag (f
))
3717 if (gc
.library
!= FLG_ANSILIB
3721 (message ("Selecting library %s after library %s was "
3722 "selected (only one library may be used)",
3723 flagcode_unparse (f
),
3724 flagcode_unparse (gc
.library
)));
3727 if (f
== FLG_UNIXLIB
)
3729 if (context_getFlag (FLG_WARNUNIXLIB
))
3732 (cstring_makeLiteral
3733 ("Selecting unix library. Unix library is "
3734 "based on the Single Unix Specification, Version 2. Not all "
3735 "Unix implementations are consistend with this specification. "
3736 "Use -warnunixlib to suppress this message."));
3743 if (flagcode_isNameChecksFlag (f
) && b
&& !context_maybeSet (FLG_NAMECHECKS
))
3747 ("Setting +%s will not produce warnings with -namechecks. "
3748 "Must set +namechecks also.",
3749 flagcode_unparse (f
)));
3752 gc
.setGlobally
[f
] = TRUE
;
3753 context_setFlag (f
, b
, g_currentloc
);
3757 context_fileSetFlag (flagcode f
, ynm set
, fileloc loc
)
3761 context_saveFlagSettings ();
3764 if (ynm_isOff (set
))
3766 context_setFlagAux (f
, FALSE
, TRUE
, FALSE
, loc
);
3768 else if (ynm_isOn (set
))
3770 context_setFlagAux (f
, TRUE
, TRUE
, FALSE
, loc
);
3771 gc
.setLocally
[f
] = TRUE
;
3775 context_restoreFlag (f
, loc
);
3780 context_restoreFlag (flagcode f
, fileloc loc
)
3786 message ("Attempt to restore flag %s when no file scope flags "
3788 flagcode_unparse (f
)),
3793 context_addFlagMarker (f
, MAYBE
, loc
);
3794 context_setFlagAux (f
, gc
.saveflags
[f
], FALSE
, TRUE
, loc
);
3800 context_setFlag (flagcode f
, bool b
, fileloc loc
)
3802 context_setFlagAux (f
, b
, FALSE
, FALSE
, loc
);
3806 context_setFlagTemp (flagcode f
, bool b
)
3808 DPRINTF (("Set flag temp: %s / %s", flagcode_unparse (f
), bool_unparse (b
)));
3813 # define DOSET(ff,b) \
3814 do { if (inFile) { gc.setLocally[ff] = TRUE; \
3815 context_addFlagMarker (ff, ynm_fromBool (b), loc); } \
3816 DPRINTF (("set flag: %s / %s", flagcode_unparse (ff), bool_unparse (b))); \
3817 gc.flags[ff] = b; } while (FALSE)
3820 context_setFlagAux (flagcode f
, bool b
, bool inFile
,
3821 /*@unused@*/ bool isRestore
, fileloc loc
)
3823 DPRINTF (("Set flag: %s / %s", flagcode_unparse (f
), bool_unparse (b
)));
3826 ** Removed test for special flags.
3829 if (flagcode_isIdemFlag (f
))
3838 if (f
>= FLG_ITS4MOSTRISKY
&& f
<= FLG_ITS4LOWRISK
)
3840 if (b
) /* Turing higher level on, turns on all lower levels */
3844 case FLG_ITS4MOSTRISKY
:
3845 DOSET (FLG_ITS4VERYRISKY
, b
);
3847 case FLG_ITS4VERYRISKY
:
3848 DOSET (FLG_ITS4RISKY
, b
);
3851 DOSET (FLG_ITS4MODERATERISK
, b
);
3853 case FLG_ITS4MODERATERISK
:
3854 DOSET (FLG_ITS4LOWRISK
, b
);
3856 case FLG_ITS4LOWRISK
:
3861 else /* Turning level off, turns off all higher levels */
3865 case FLG_ITS4LOWRISK
:
3866 DOSET (FLG_ITS4MODERATERISK
, b
);
3868 case FLG_ITS4MODERATERISK
:
3869 DOSET (FLG_ITS4RISKY
, b
);
3872 DOSET (FLG_ITS4VERYRISKY
, b
);
3874 case FLG_ITS4VERYRISKY
:
3875 DOSET (FLG_ITS4MOSTRISKY
, b
);
3877 case FLG_ITS4MOSTRISKY
:
3886 case FLG_MESSAGESTREAMSTDOUT
:
3887 g_messagestream
= stdout
;
3889 case FLG_MESSAGESTREAMSTDERR
:
3890 g_messagestream
= stderr
;
3892 case FLG_WARNINGSTREAMSTDOUT
:
3893 g_warningstream
= stdout
;
3895 case FLG_WARNINGSTREAMSTDERR
:
3896 g_warningstream
= stderr
;
3898 case FLG_ERRORSTREAMSTDOUT
:
3899 g_errorstream
= stdout
;
3901 case FLG_ERRORSTREAMSTDERR
:
3902 g_errorstream
= stderr
;
3905 DOSET (FLG_ALLEMPTY
, b
);
3906 DOSET (FLG_IFEMPTY
, b
);
3907 DOSET (FLG_WHILEEMPTY
, b
);
3908 DOSET (FLG_FOREMPTY
, b
);
3911 DOSET (FLG_PREDBOOL
, b
);
3912 DOSET (FLG_PREDBOOLINT
, b
);
3913 DOSET (FLG_PREDBOOLPTR
, b
);
3914 DOSET (FLG_PREDBOOLOTHERS
, b
);
3917 DOSET (FLG_CHECKSTRICTGLOBALIAS
, b
);
3918 DOSET (FLG_CHECKEDGLOBALIAS
, b
);
3919 DOSET (FLG_CHECKMODGLOBALIAS
, b
);
3920 DOSET (FLG_UNCHECKEDGLOBALIAS
, b
);
3923 DOSET (FLG_ALLBLOCK
, b
);
3924 DOSET (FLG_IFBLOCK
, b
);
3925 DOSET (FLG_WHILEBLOCK
, b
);
3926 DOSET (FLG_FORBLOCK
, b
);
3940 DOSET (FLG_GRAMMAR
, b
);
3942 case FLG_CODEIMPONLY
:
3943 DOSET (FLG_CODEIMPONLY
, b
);
3944 DOSET (FLG_GLOBIMPONLY
, b
);
3945 DOSET (FLG_RETIMPONLY
, b
);
3946 DOSET (FLG_STRUCTIMPONLY
, b
);
3948 case FLG_SPECALLIMPONLY
:
3949 DOSET (FLG_SPECALLIMPONLY
, b
);
3950 DOSET (FLG_SPECGLOBIMPONLY
, b
);
3951 DOSET (FLG_SPECRETIMPONLY
, b
);
3952 DOSET (FLG_SPECSTRUCTIMPONLY
, b
);
3954 case FLG_ALLIMPONLY
:
3955 DOSET (FLG_ALLIMPONLY
, b
);
3956 DOSET (FLG_GLOBIMPONLY
, b
);
3957 DOSET (FLG_RETIMPONLY
, b
);
3958 DOSET (FLG_STRUCTIMPONLY
, b
);
3959 DOSET (FLG_SPECGLOBIMPONLY
, b
);
3960 DOSET (FLG_SPECRETIMPONLY
, b
);
3961 DOSET (FLG_SPECSTRUCTIMPONLY
, b
);
3963 case FLG_ANSI89LIMITS
:
3964 DOSET (FLG_ANSI89LIMITS
, b
);
3965 DOSET (FLG_CONTROLNESTDEPTH
, b
);
3966 DOSET (FLG_STRINGLITERALLEN
, b
);
3967 DOSET (FLG_INCLUDENEST
, b
);
3968 DOSET (FLG_NUMSTRUCTFIELDS
, b
);
3969 DOSET (FLG_NUMENUMMEMBERS
, b
);
3973 context_setValue (FLG_CONTROLNESTDEPTH
, ANSI89_CONTROLNESTDEPTH
);
3974 context_setValue (FLG_STRINGLITERALLEN
, ANSI89_STRINGLITERALLEN
);
3975 context_setValue (FLG_INCLUDENEST
, ANSI89_INCLUDENEST
);
3976 context_setValue (FLG_NUMSTRUCTFIELDS
, ANSI89_NUMSTRUCTFIELDS
);
3977 context_setValue (FLG_NUMENUMMEMBERS
, ANSI89_NUMENUMMEMBERS
);
3978 context_setValue (FLG_EXTERNALNAMELEN
, ANSI89_EXTERNALNAMELEN
);
3979 context_setValue (FLG_INTERNALNAMELEN
, ANSI89_INTERNALNAMELEN
);
3982 case FLG_ISO99LIMITS
:
3983 DOSET (FLG_ISO99LIMITS
, b
);
3984 DOSET (FLG_CONTROLNESTDEPTH
, b
);
3985 DOSET (FLG_STRINGLITERALLEN
, b
);
3986 DOSET (FLG_INCLUDENEST
, b
);
3987 DOSET (FLG_NUMSTRUCTFIELDS
, b
);
3988 DOSET (FLG_NUMENUMMEMBERS
, b
);
3992 context_setValue (FLG_CONTROLNESTDEPTH
, ISO99_CONTROLNESTDEPTH
);
3993 context_setValue (FLG_STRINGLITERALLEN
, ISO99_STRINGLITERALLEN
);
3994 context_setValue (FLG_INCLUDENEST
, ISO99_INCLUDENEST
);
3995 context_setValue (FLG_NUMSTRUCTFIELDS
, ISO99_NUMSTRUCTFIELDS
);
3996 context_setValue (FLG_NUMENUMMEMBERS
, ISO99_NUMENUMMEMBERS
);
3997 context_setValue (FLG_EXTERNALNAMELEN
, ISO99_EXTERNALNAMELEN
);
3998 context_setValue (FLG_INTERNALNAMELEN
, ISO99_INTERNALNAMELEN
);
4001 case FLG_EXTERNALNAMELEN
:
4002 DOSET (FLG_DISTINCTEXTERNALNAMES
, TRUE
);
4003 DOSET (FLG_EXTERNALNAMELEN
, TRUE
);
4005 case FLG_INTERNALNAMELEN
:
4006 DOSET (FLG_DISTINCTINTERNALNAMES
, TRUE
);
4007 DOSET (FLG_INTERNALNAMELEN
, TRUE
);
4009 case FLG_EXTERNALNAMECASEINSENSITIVE
:
4010 DOSET (FLG_EXTERNALNAMECASEINSENSITIVE
, b
);
4012 if (b
&& !gc
.flags
[FLG_DISTINCTEXTERNALNAMES
])
4014 DOSET (FLG_DISTINCTEXTERNALNAMES
, TRUE
);
4015 context_setValue (FLG_EXTERNALNAMELEN
, 0);
4018 case FLG_INTERNALNAMECASEINSENSITIVE
:
4019 DOSET (FLG_INTERNALNAMECASEINSENSITIVE
, b
);
4021 if (b
&& !gc
.flags
[FLG_DISTINCTINTERNALNAMES
])
4023 DOSET (FLG_DISTINCTINTERNALNAMES
, TRUE
);
4024 context_setValue (FLG_INTERNALNAMELEN
, 0);
4027 case FLG_INTERNALNAMELOOKALIKE
:
4028 DOSET (FLG_INTERNALNAMELOOKALIKE
, b
);
4030 if (b
&& !gc
.flags
[FLG_DISTINCTINTERNALNAMES
])
4032 DOSET (FLG_DISTINCTINTERNALNAMES
, TRUE
);
4033 context_setValue (FLG_INTERNALNAMELEN
, 0);
4037 DOSET (FLG_MODNOMODS
, b
);
4038 DOSET (FLG_MODGLOBSUNSPEC
, b
);
4039 DOSET (FLG_MODSTRICTGLOBSUNSPEC
, b
);
4042 DOSET (FLG_EXPORTVAR
, b
);
4043 DOSET (FLG_EXPORTFCN
, b
);
4044 DOSET (FLG_EXPORTTYPE
, b
);
4045 DOSET (FLG_EXPORTMACRO
, b
);
4046 DOSET (FLG_EXPORTCONST
, b
);
4047 gc
.anyExports
= TRUE
;
4050 DOSET (FLG_RETEXPOSE
, b
);
4051 DOSET (FLG_ASSIGNEXPOSE
, b
);
4052 DOSET (FLG_CASTEXPOSE
, b
);
4055 DOSET (FLG_RETVALBOOL
, b
);
4056 DOSET (FLG_RETVALINT
, b
);
4057 DOSET (FLG_RETVALOTHER
, b
);
4062 DOSET (FLG_EXPORTLOCAL
, FALSE
);
4063 DOSET (FLG_DECLUNDEF
, FALSE
);
4064 DOSET (FLG_SPECUNDEF
, FALSE
);
4065 DOSET (FLG_TOPUNUSED
, FALSE
);
4069 DOSET (FLG_LOOPLOOPBREAK
, b
);
4070 DOSET (FLG_LOOPSWITCHBREAK
, b
);
4071 DOSET (FLG_SWITCHLOOPBREAK
, b
);
4072 DOSET (FLG_SWITCHSWITCHBREAK
, b
);
4073 DOSET (FLG_LOOPLOOPCONTINUE
, b
);
4074 DOSET (FLG_DEEPBREAK
, b
);
4077 DOSET (FLG_FORLOOPEXEC
, b
);
4078 DOSET (FLG_WHILELOOPEXEC
, b
);
4079 DOSET (FLG_ITERLOOPEXEC
, b
);
4082 DOSET (FLG_ACCESSMODULE
, b
);
4083 DOSET (FLG_ACCESSFILE
, b
);
4084 DOSET (FLG_ACCESSCZECH
, b
);
4087 DOSET (FLG_ALLMACROS
, b
);
4088 DOSET (FLG_FCNMACROS
, b
);
4089 DOSET (FLG_CONSTMACROS
, b
);
4092 DOSET (FLG_BOUNDSREAD
, b
);
4093 DOSET (FLG_BOUNDSWRITE
, b
);
4094 DOSET (FLG_LIKELYBOUNDSREAD
, b
);
4095 DOSET (FLG_LIKELYBOUNDSWRITE
, b
);
4097 case FLG_BOUNDSREAD
:
4098 DOSET (FLG_LIKELYBOUNDSREAD
, b
);
4100 case FLG_BOUNDSWRITE
:
4101 DOSET (FLG_LIKELYBOUNDSWRITE
, b
);
4103 case FLG_LIKELYBOUNDS
:
4104 DOSET (FLG_LIKELYBOUNDSREAD
, b
);
4105 DOSET (FLG_LIKELYBOUNDSWRITE
, b
);
4109 if (b
) { DOSET (FLG_ACCESSCZECH
, b
); }
4110 DOSET (FLG_CZECHFUNCTIONS
, b
);
4111 DOSET (FLG_CZECHVARS
, b
);
4112 DOSET (FLG_CZECHCONSTANTS
, b
);
4113 DOSET (FLG_CZECHTYPES
, b
);
4116 if (b
) { DOSET (FLG_ACCESSSLOVAK
, b
); }
4117 DOSET (FLG_SLOVAKFUNCTIONS
, b
);
4118 DOSET (FLG_SLOVAKVARS
, b
);
4119 DOSET (FLG_SLOVAKCONSTANTS
, b
);
4120 DOSET (FLG_SLOVAKTYPES
, b
);
4122 case FLG_CZECHOSLOVAK
:
4123 if (b
) { DOSET (FLG_ACCESSCZECHOSLOVAK
, b
); }
4124 DOSET (FLG_CZECHOSLOVAKFUNCTIONS
, b
);
4125 DOSET (FLG_CZECHOSLOVAKVARS
, b
);
4126 DOSET (FLG_CZECHOSLOVAKCONSTANTS
, b
);
4127 DOSET (FLG_CZECHOSLOVAKTYPES
, b
);
4130 DOSET (FLG_NULLSTATE
, b
);
4131 DOSET (FLG_NULLDEREF
, b
);
4132 DOSET (FLG_NULLASSIGN
, b
);
4133 DOSET (FLG_NULLPASS
, b
);
4134 DOSET (FLG_NULLRET
, b
);
4137 DOSET (FLG_MUSTFREEONLY
, b
);
4138 DOSET (FLG_MUSTFREEFRESH
, b
);
4141 DOSET (FLG_NULLSTATE
, b
);
4142 DOSET (FLG_NULLDEREF
, b
);
4143 DOSET (FLG_NULLASSIGN
, b
);
4144 DOSET (FLG_NULLPASS
, b
);
4145 DOSET (FLG_NULLRET
, b
);
4146 DOSET (FLG_COMPDEF
, b
);
4147 DOSET (FLG_COMPMEMPASS
, b
);
4148 DOSET (FLG_UNIONDEF
, b
);
4149 DOSET (FLG_MEMTRANS
, b
);
4150 DOSET (FLG_USERELEASED
, b
);
4151 DOSET (FLG_ALIASUNIQUE
, b
);
4152 DOSET (FLG_MAYALIASUNIQUE
, b
);
4153 DOSET (FLG_MUSTFREEONLY
, b
);
4154 DOSET (FLG_MUSTFREEFRESH
, b
);
4155 DOSET (FLG_MUSTDEFINE
, b
);
4156 DOSET (FLG_GLOBSTATE
, b
);
4157 DOSET (FLG_COMPDESTROY
, b
);
4158 DOSET (FLG_MUSTNOTALIAS
, b
);
4159 DOSET (FLG_MEMIMPLICIT
, b
);
4160 DOSET (FLG_BRANCHSTATE
, b
);
4161 /*@fallthrough@*/ /* also sets memtrans flags */
4163 DOSET (FLG_MEMTRANS
, b
);
4164 DOSET (FLG_EXPOSETRANS
, b
);
4165 DOSET (FLG_OBSERVERTRANS
, b
);
4166 DOSET (FLG_DEPENDENTTRANS
, b
);
4167 DOSET (FLG_NEWREFTRANS
, b
);
4168 DOSET (FLG_ONLYTRANS
, b
);
4169 DOSET (FLG_OWNEDTRANS
, b
);
4170 DOSET (FLG_FRESHTRANS
, b
);
4171 DOSET (FLG_SHAREDTRANS
, b
);
4172 DOSET (FLG_TEMPTRANS
, b
);
4173 DOSET (FLG_KEPTTRANS
, b
);
4174 DOSET (FLG_REFCOUNTTRANS
, b
);
4175 DOSET (FLG_STATICTRANS
, b
);
4176 DOSET (FLG_UNKNOWNTRANS
, b
);
4177 DOSET (FLG_KEEPTRANS
, b
);
4178 DOSET (FLG_IMMEDIATETRANS
, b
);
4185 if (b
&& !gc
.anyExports
4186 && (f
== FLG_EXPORTVAR
|| f
== FLG_EXPORTFCN
4187 || f
== FLG_EXPORTTYPE
|| f
== FLG_EXPORTMACRO
4188 || f
== FLG_EXPORTCONST
4189 || f
== FLG_EXPORTANY
))
4191 gc
.anyExports
= TRUE
;
4196 context_maybeSet (flagcode d
)
4198 return (gc
.flags
[d
] || gc
.setLocally
[d
]);
4202 context_getFlag (flagcode d
)
4204 return (gc
.flags
[d
]);
4208 context_flagOn (flagcode f
, fileloc loc
)
4210 return (!context_suppressFlagMsg (f
, loc
));
4213 static void context_saveFlagSettings (void)
4215 gc
.savedFlags
= TRUE
;
4216 llassert (sizeof (gc
.saveflags
) == sizeof (gc
.flags
));
4217 memcpy (gc
.saveflags
, gc
.flags
, sizeof (gc
.flags
));
4220 static void context_restoreFlagSettings (void)
4222 llassert (sizeof (gc
.saveflags
) == sizeof (gc
.flags
));
4223 memcpy (gc
.flags
, gc
.saveflags
, sizeof (gc
.flags
));
4224 gc
.savedFlags
= FALSE
;
4227 void context_setFilename (fileId fid
, int lineno
)
4228 /*@globals fileloc g_currentloc;@*/
4229 /*@modifies g_currentloc@*/
4231 if (fileId_baseEqual (currentFile (), fid
))
4238 fileloc_setColumn (g_currentloc
, 0);
4240 if (fileloc_isSpecialFile (g_currentloc
))
4242 gc
.inDerivedFile
= TRUE
;
4245 if (filelocStack_popPushFile (gc
.locstack
, g_currentloc
))
4247 int maxdepth
= context_getValue (FLG_INCLUDENEST
);
4249 if (filelocStack_size (gc
.locstack
) > maxdepth
)
4251 int depth
= filelocStack_includeDepth (gc
.locstack
);
4253 if (depth
> maxdepth
)
4257 message ("Maximum include nesting depth "
4258 "(%d, current depth %d) exceeded",
4261 filelocStack_nextTop (gc
.locstack
)))
4263 filelocStack_printIncludes (gc
.locstack
);
4269 g_currentloc
= fileloc_create (fid
, lineno
, 1);
4271 context_enterFileAux ();
4275 void context_enterIterDef (/*@observer@*/ uentry le
)
4277 context_enterMacro (le
);
4278 gc
.acct
= typeIdSet_subtract (gc
.facct
, gc
.nacct
);
4279 gc
.kind
= CX_ITERDEF
;
4282 void context_enterIterEnd (/*@observer@*/ uentry le
)
4284 context_enterMacro (le
);
4285 gc
.kind
= CX_ITEREND
;
4289 context_destroyMod (void)
4290 /*@globals killed gc@*/
4294 ctype_destroyMod ();
4301 fileTable_free (gc
.ftab
);
4302 gc
.ftab
= fileTable_undefined
;
4304 filelocStack_free (gc
.locstack
);
4307 macrocache_free (gc
.mc
);
4309 /* evans 2002-07-12: not reported because of reldef */
4310 for (i
= 0; i
< gc
.nmods
; i
++)
4312 cstring_free (gc
.moduleaccess
[i
].file
);
4315 sfree (gc
.moduleaccess
);
4318 fileloc_free (gc
.saveloc
); gc
.saveloc
= fileloc_undefined
;
4319 fileloc_free (gc
.pushloc
); gc
.pushloc
= fileloc_undefined
;
4322 sRefSetList_free (gc
.modrecs
);
4324 flagMarkerList_free (gc
.markers
);
4326 messageLog_free (gc
.msgLog
);
4328 clauseStack_free (gc
.clauses
);
4331 cstring_free (gc
.msgAnnote
);
4332 globSet_free (gc
.globs_used
);
4333 metaStateTable_free (gc
.stateTable
);
4334 annotationTable_free (gc
.annotTable
);
4341 bool context_msgBoolInt (void)
4343 return context_flagOn (FLG_BOOLINT
, g_currentloc
);
4346 bool context_msgCharInt (void)
4348 return context_flagOn (FLG_CHARINT
, g_currentloc
);
4351 bool context_msgEnumInt (void)
4353 return context_flagOn (FLG_ENUMINT
, g_currentloc
);
4356 bool context_msgLongInt (void)
4358 return context_flagOn (FLG_LONGINT
, g_currentloc
);
4361 bool context_msgShortInt (void)
4363 return context_flagOn (FLG_SHORTINT
, g_currentloc
);
4366 bool context_msgPointerArith (void)
4368 return context_flagOn (FLG_POINTERARITH
, g_currentloc
);
4371 bool context_msgStrictOps (void)
4373 return context_flagOn (FLG_STRICTOPS
, g_currentloc
);
4376 bool context_msgLh (void)
4378 return gc
.flags
[FLG_DOLH
];
4381 void context_pushLoc (void)
4383 fileloc_free (gc
.pushloc
);
4384 gc
.pushloc
= gc
.saveloc
;
4385 gc
.saveloc
= fileloc_undefined
;
4388 void context_popLoc (void)
4390 gc
.saveloc
= fileloc_update (gc
.saveloc
, gc
.pushloc
);
4393 bool context_inGlobalScope (void)
4395 return (usymtab_inFileScope() || usymtab_inGlobalScope ());
4398 bool context_inInnerScope (void)
4400 return (gc
.kind
== CX_INNER
);
4403 void context_setProtectVars (void)
4405 gc
.protectVars
= TRUE
;
4408 bool context_anyErrors (void)
4410 return (gc
.numerrors
> 0);
4413 void context_hasError (void)
4416 DPRINTF (("num errors: %d", gc
.numerrors
));
4419 int context_numErrors (void)
4421 return gc
.numerrors
;
4424 bool context_neednl (void)
4429 void context_setNeednl (void)
4434 int context_getExpect (void)
4436 return (context_getValue (FLG_EXPECT
));
4439 int context_getLCLExpect (void)
4441 return (context_getValue (FLG_LCLEXPECT
));
4444 int context_getLimit (void)
4446 return (context_getValue (FLG_LIMIT
));
4449 bool context_unlimitedMessages (void)
4451 return (context_getLimit () < 0);
4454 void context_releaseVars (void)
4456 llassert (gc
.protectVars
);
4457 gc
.protectVars
= FALSE
;
4460 void context_sizeofReleaseVars (void)
4462 /* If there is a nested sizeof, this might not hold:
4463 llassert (gc.protectVars);
4466 gc
.protectVars
= FALSE
;
4469 bool context_inProtectVars (void)
4471 return (gc
.protectVars
);
4475 void context_hideShowscan (void)
4477 gc
.flags
[FLG_SHOWSCAN
] = FALSE
;
4480 void context_unhideShowscan (void)
4482 gc
.flags
[FLG_SHOWSCAN
] = TRUE
;
4484 # endif /* DEADCODE */
4486 bool context_inHeader (void)
4488 return (gc
.inheader
);
4491 fileTable
context_fileTable (void)
4496 cstring
context_tmpdir (void)
4498 return (context_getString (FLG_TMPDIR
));
4501 messageLog
context_messageLog (void)
4506 bool context_inMacroFunction (void)
4508 return (gc
.kind
== CX_MACROFCN
);
4511 bool context_inMacroConstant (void)
4513 return (gc
.kind
== CX_MACROCONST
);
4516 bool context_inUnknownMacro (void)
4518 return (gc
.kind
== CX_UNKNOWNMACRO
);
4521 void context_setShownFunction (void)
4523 gc
.showfunction
= FALSE
;
4526 bool context_doDump (void)
4528 return cstring_isNonEmpty (context_getString (FLG_DUMP
));
4531 bool context_doMerge (void)
4533 return cstring_isNonEmpty (context_getString (FLG_MERGE
));
4536 cstring
context_getDump (void)
4538 return context_getString (FLG_DUMP
);
4541 cstring
context_getMerge (void)
4543 return context_getString (FLG_MERGE
);
4546 bool context_inLCLLib (void)
4548 return (gc
.kind
== CX_LCLLIB
);
4552 /*drl add these 3/5/2003*/
4553 static bool inSizeof
= FALSE
;
4555 bool context_inSizeof (void)
4560 void context_enterSizeof (void)
4562 DPRINTF((message("context_enterSizeof ") ) );
4566 void context_leaveSizeof (void)
4568 DPRINTF((message("context_leaveSizeof ") ));
4571 /*end function added 3/5/2003*/
4574 bool context_inImport (void)
4576 return (gc
.inimport
);
4579 void context_enterImport (void)
4584 void context_leaveImport (void)
4586 gc
.inimport
= FALSE
;
4589 bool context_inMacro (void)
4591 return (gc
.kind
== CX_MACROFCN
|| gc
.kind
== CX_MACROCONST
4592 || gc
.kind
== CX_UNKNOWNMACRO
4593 || gc
.kind
== CX_ITERDEF
|| gc
.kind
== CX_ITEREND
);
4596 bool context_inIterDef (void)
4598 return (gc
.kind
== CX_ITERDEF
);
4601 bool context_inIterEnd (void)
4603 return (gc
.kind
== CX_ITEREND
);
4606 int context_getLinesProcessed (void)
4608 return (gc
.linesprocessed
);
4611 int context_getSpecLinesProcessed (void)
4613 return (gc
.speclinesprocessed
);
4616 void context_processedSpecLine (void)
4618 gc
.speclinesprocessed
++;
4621 void context_resetSpecLines (void)
4623 gc
.speclinesprocessed
= 0;
4627 bool context_inGlobalContext (void)
4629 return (gc
.kind
== CX_GLOBAL
);
4632 static void context_quietExitScopes (void)
4635 ** Try to restore the global scope (after an error).
4638 while (!usymtab_inFileScope ())
4640 usymtab_quietExitScope (g_currentloc
);
4643 gc
.cont
.glob
= TRUE
;
4644 gc
.kind
= CX_GLOBAL
;
4647 void context_checkGlobalScope (void)
4649 if (gc
.kind
!= CX_GLOBAL
)
4651 if (context_inMacro ())
4653 ; /* evans 2001-10-14: Okay to be in a macro here! */
4657 llcontbug (message ("Not in global scope as expected: %q", context_unparse ()));
4658 context_quietExitScopes ();
4663 void context_setFileId (fileId s
)
4665 g_currentloc
= fileloc_updateFileId (g_currentloc
, s
);
4668 bool context_setBoolName (void)
4670 return (!cstring_equalLit (context_getString (FLG_BOOLTYPE
),
4674 cstring
context_printBoolName (void)
4676 if (context_setBoolName ())
4678 return context_getBoolName ();
4682 return cstring_makeLiteralTemp ("boolean");
4686 cstring
context_getBoolName (void)
4688 return (context_getString (FLG_BOOLTYPE
));
4691 cstring
context_getFalseName (void)
4693 return (context_getString (FLG_BOOLFALSE
));
4696 cstring
context_getTrueName (void)
4698 return (context_getString (FLG_BOOLTRUE
));
4701 cstring
context_getLarchPath (void)
4703 return (context_getString (FLG_LARCHPATH
));
4706 cstring
context_getLCLImportDir (void)
4708 return (context_getString (FLG_LCLIMPORTDIR
));
4711 static void context_setJustPopped (void)
4713 gc
.justpopped
= TRUE
;
4716 void context_clearJustPopped (void)
4718 gc
.justpopped
= FALSE
;
4721 bool context_justPopped (void)
4723 return (gc
.justpopped
);
4726 void context_setMacroMissingParams (void)
4728 gc
.macroMissingParams
= TRUE
;
4731 void context_resetMacroMissingParams (void)
4733 gc
.macroMissingParams
= FALSE
;
4736 bool context_isMacroMissingParams (void)
4738 return (gc
.macroMissingParams
);
4742 void context_showFilelocStack (void)
4744 filelocStack_printIncludes (gc
.locstack
);
4747 metaStateTable
context_getMetaStateTable (void)
4749 return gc
.stateTable
;
4751 # endif /* DEADCODE */
4753 metaStateInfo
context_lookupMetaStateInfo (cstring key
)
4755 return metaStateTable_lookup (gc
.stateTable
, key
);
4758 /*@null@*/ annotationInfo
context_lookupAnnotation (cstring annot
)
4760 return annotationTable_lookup (gc
.annotTable
, annot
);
4763 void context_addAnnotation (annotationInfo info
)
4765 if (annotationTable_contains (gc
.annotTable
, annotationInfo_getName (info
)))
4769 message ("Duplicate annotation declaration: %s", annotationInfo_getName (info
)),
4770 annotationInfo_getLoc (info
));
4772 annotationInfo_free (info
);
4776 annotationTable_insert (gc
.annotTable
, info
);
4780 void context_addMetaState (cstring mname
, metaStateInfo msinfo
)
4782 if (metaStateTable_contains (gc
.stateTable
, mname
))
4786 message ("Duplicate metastate declaration: %s", mname
),
4787 metaStateInfo_getLoc (msinfo
));
4788 cstring_free (mname
);
4789 metaStateInfo_free (msinfo
);
4793 DPRINTF (("Adding meta state: %s", mname
));
4794 metaStateTable_insert (gc
.stateTable
, mname
, msinfo
);
4798 valueTable
context_createValueTable (sRef s
, stateInfo info
)
4800 if (metaStateTable_size (gc
.stateTable
) > 0)
4802 valueTable res
= valueTable_create (metaStateTable_size (gc
.stateTable
));
4803 /* should use smaller value... */
4804 DPRINTF (("Value table for: %s", sRef_unparse (s
)));
4806 metaStateTable_elements (gc
.stateTable
, msname
, msi
)
4808 mtContextNode context
= metaStateInfo_getContext (msi
);
4810 if (mtContextNode_matchesRefStrict (context
, s
))
4812 DPRINTF (("Create: %s", metaStateInfo_unparse (msi
)));
4813 llassert (cstring_equal (msname
, metaStateInfo_getName (msi
)));
4817 cstring_copy (metaStateInfo_getName (msi
)),
4818 stateValue_createImplicit (metaStateInfo_getDefaultValue (msi
, s
),
4819 stateInfo_copy (info
)));
4823 DPRINTF (("No match: %s", metaStateInfo_unparse (msi
)));
4826 end_metaStateTable_elements
;
4828 stateInfo_free (info
);
4829 DPRINTF (("Value table: %s", valueTable_unparse (res
)));
4834 stateInfo_free (info
);
4835 return valueTable_undefined
;
4839 valueTable
context_createGlobalMarkerValueTable (stateInfo info
)
4841 if (metaStateTable_size (gc
.stateTable
) > 0)
4843 valueTable res
= valueTable_create (metaStateTable_size (gc
.stateTable
));
4844 /* should use smaller value... */
4846 metaStateTable_elements (gc
.stateTable
, msname
, msi
)
4848 /* only add global...*/
4849 DPRINTF (("Create: %s", metaStateInfo_unparse (msi
)));
4850 llassert (cstring_equal (msname
, metaStateInfo_getName (msi
)));
4852 valueTable_insert (res
,
4853 cstring_copy (metaStateInfo_getName (msi
)),
4854 stateValue_create (metaStateInfo_getDefaultGlobalValue (msi
),
4855 stateInfo_copy (info
)));
4857 end_metaStateTable_elements
;
4859 stateInfo_free (info
);
4860 DPRINTF (("Value table: %s", valueTable_unparse (res
)));
4865 stateInfo_free (info
);
4866 return valueTable_undefined
;
4870 constraintList
context_getImplicitFcnConstraints (uentry ue
)
4872 constraintList ret
= constraintList_makeNew ();
4873 uentryList params
= uentry_getParams (ue
);
4875 uentryList_elements (params
, el
)
4877 DPRINTF (("setImplicitfcnConstraints doing: %s", uentry_unparse(el
)));
4879 if (uentry_isElipsisMarker (el
))
4885 sRef s
= uentry_getSref (el
);
4887 DPRINTF (("Trying: %s", sRef_unparse (s
)));
4889 if (ctype_isPointer (sRef_getType (s
)))
4891 constraint c
= constraint_makeSRefWriteSafeInt (s
, 0);
4892 ret
= constraintList_add (ret
, c
);
4894 /*drl 10/23/2002 added support for out*/
4896 if (!uentry_isOut(el
))
4898 c
= constraint_makeSRefReadSafeInt (s
, 0);
4899 ret
= constraintList_add (ret
, c
);
4904 DPRINTF (("%s is NOT a pointer", sRef_unparseFull (s
)));
4907 } end_uentryList_elements
;
4909 DPRINTF (("Returns ==> %s", constraintList_unparse (ret
)));