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"
42 /*@constant observer const char *LARCHDIR; @*/
43 # define LARCHDIR PKGDATADIR CONNECTSTR DEFAULT_LARCHDIR
44 /*@constant observer const char *LCLDIR; @*/
45 # define LCLDIR PKGDATADIR CONNECTSTR DEFAULT_LCLDIR
58 CX_FUNCTION
, CX_FCNDECLARATION
,
59 CX_MACROFCN
, CX_MACROCONST
, CX_UNKNOWNMACRO
,
60 CX_ITERDEF
, CX_ITEREND
,
61 CX_OLDSTYLESCOPE
, /* Parsing old-style parameter declarations */
62 CX_LCL
, CX_LCLLIB
, CX_MT
68 int speclinesprocessed
;
70 flagMarkerList markers
;
73 ** used to record state where a macro must match a function name
74 ** (i.e., no params were listed in the macro definition
77 bool macroMissingParams BOOLBITS
;
78 bool preprocessing BOOLBITS
;
79 bool incommandline BOOLBITS
;
80 bool insuppressregion BOOLBITS
;
81 bool inDerivedFile BOOLBITS
;
82 bool instandardlib BOOLBITS
;
83 bool inimport BOOLBITS
;
84 bool inheader BOOLBITS
;
85 bool inmacrocache BOOLBITS
;
86 bool protectVars BOOLBITS
;
88 bool showfunction BOOLBITS
;
89 bool savedFlags BOOLBITS
;
90 bool justpopped BOOLBITS
;
91 bool anyExports BOOLBITS
;
92 bool inFunctionHeader BOOLBITS
;
106 filelocStack locstack
;
109 /*@observer@*/ sRef aliasAnnote
;
110 /*@observer@*/ sRef aliasAnnoteAls
;
114 /*@observer@*/ sRefSet mods
;
116 /* file access types */
119 /* local access types (this function) */
122 /* no access types (@noaccess) */
125 /*@observer@*/ globSet globs
;
126 /*@only@*/ globSet globs_used
;
130 /*@reldef@*/ maccesst
*moduleaccess
; /* Not defined is nmods == 0. */
136 bool flags
[NUMFLAGS
];
137 bool saveflags
[NUMFLAGS
];
138 bool setGlobally
[NUMFLAGS
];
139 bool setLocally
[NUMFLAGS
];
141 int values
[NUMVALUEFLAGS
];
142 int counters
[NUMVALUEFLAGS
];
144 o_cstring strings
[NUMSTRINGFLAGS
];
145 sRefSetList modrecs
; /* Keep track of file static symbols modified. */
147 metaStateTable stateTable
; /* User-defined state information. */
148 annotationTable annotTable
; /* User-defined annotations table. */
153 /*@dependent@*/ /*@exposed@*/ uentry fcn
;
157 union u_cont savecont
;
160 static /*@exposed@*/ cstring
context_exposeString (flagcode p_flag
) ;
161 static void context_restoreFlagSettings (void) /*@modifies gc@*/ ;
162 static void context_saveFlagSettings (void) /*@modifies gc@*/ ;
163 static void context_exitClauseSimp (void) /*@modifies gc@*/ ;
164 static void context_setJustPopped (void) /*@modifies gc.justpopped@*/ ;
165 static void context_setValue (flagcode p_flag
, int p_val
) /*@modifies gc.flags@*/ ;
166 static void context_setFlag (flagcode p_f
, bool p_b
, fileloc p_loc
)
167 /*@modifies gc.flags@*/ ;
170 context_setFlagAux (flagcode p_f
, bool p_b
, bool p_inFile
,
171 bool p_isRestore
, fileloc p_loc
)
172 /*@modifies gc.flags@*/ ;
174 static void context_restoreFlag (flagcode p_f
, fileloc p_loc
)
175 /*@modifies gc.flags@*/ ;
180 cstring
context_unparseFlagMarkers (void)
182 return (flagMarkerList_unparse (gc
.markers
));
184 # endif /* DEADCODE */
186 void context_setPreprocessing (void)
188 llassert (!gc
.preprocessing
);
189 gc
.preprocessing
= TRUE
;
192 void context_clearPreprocessing (void)
194 llassert (gc
.preprocessing
);
195 gc
.preprocessing
= FALSE
;
198 bool context_isPreprocessing (void)
200 return gc
.preprocessing
;
203 bool context_loadingLibrary (void)
205 return (fileloc_isLib (g_currentloc
));
208 bool context_inXHFile (void)
210 return (fileloc_isXHFile (g_currentloc
));
213 void context_setInCommandLine (void)
215 llassert (!gc
.incommandline
);
216 gc
.incommandline
= TRUE
;
219 void context_clearInCommandLine (void)
221 llassert (gc
.incommandline
);
222 gc
.incommandline
= FALSE
;
225 bool context_isInCommandLine (void)
227 return gc
.incommandline
;
231 void pushClause (clause c
) /*@modifies gc.clauses, gc.inclause@*/
234 clauseStack_push (gc
.clauses
, c
);
236 if (clause_isConditional (c
)
237 && context_getFlag (FLG_CONTROLNESTDEPTH
))
239 int maxdepth
= context_getValue (FLG_CONTROLNESTDEPTH
);
240 int depth
= clauseStack_controlDepth (gc
.clauses
);
242 if (depth
== maxdepth
+ 1)
245 (FLG_CONTROLNESTDEPTH
,
246 message ("Maximum control nesting depth "
255 clause
topClause (clauseStack s
) /*@*/
257 if (clauseStack_isEmpty (s
)) return NOCLAUSE
;
258 return ((clause
) clauseStack_top (s
));
262 context_addMacroCache (/*@only@*/ cstring def
)
264 DPRINTF (("macro cache: %s", def
));
265 macrocache_addEntry (gc
.mc
, fileloc_copy (g_currentloc
), def
);
269 context_addComment (/*@only@*/ cstring def
, fileloc loc
)
271 macrocache_addComment (gc
.mc
, fileloc_copy (loc
), def
);
275 ** returns TRUE is fl is in ignore region, or region where -code
277 ** the logic is fuzzy...
281 context_inSuppressFlagZone (fileloc fl
, flagcode code
)
283 ynm ret
= flagMarkerList_suppressError (gc
.markers
, code
, fl
);
286 if (ynm_isMaybe (ret
))
294 res
= !gc
.saveflags
[code
];
298 res
= !context_getFlag (code
);
303 res
= ynm_toBoolStrict (ret
);
310 context_suppressSystemMsg (fileloc fl
)
312 if (context_getFlag (FLG_SYSTEMDIRERRORS
))
318 return (fileloc_isSystemFile (fl
));
323 context_suppressFlagMsg (flagcode flag
, fileloc fl
)
325 if (context_suppressSystemMsg (fl
))
330 DPRINTF (("Checking suppress: %s / %s", fileloc_unparse (fl
), fileloc_unparse (g_currentloc
)));
332 /* want same object compare here */
334 if (fileloc_equal (fl
, g_currentloc
) || gc
.inDerivedFile
)
336 DPRINTF (("In derived file: %s", bool_unparse (gc
.inDerivedFile
)));
338 return (!context_getFlag (flag
)
339 || context_inSuppressRegion ()
340 || context_inSuppressZone (fl
)
341 || (context_inSuppressFlagZone (fl
, flag
))); /* removed gc.inDerivedFile from this */
345 return (context_inSuppressFlagZone (fl
, flag
));
350 context_suppressNotFlagMsg (flagcode flag
, fileloc fl
)
353 if (context_suppressSystemMsg (fl
))
359 if (fl
== g_currentloc
)
360 /*@noaccess fileloc@*/
362 return (context_getFlag (flag
) || context_inSuppressRegion ());
367 return (context_getFlag (flag
) || context_inSuppressRegion ());
372 context_inSuppressZone (fileloc fl
)
374 if (context_suppressSystemMsg (fl
))
379 return (flagMarkerList_inIgnore (gc
.markers
, fl
));
383 context_inSuppressRegion (void)
385 return (gc
.insuppressregion
);
389 context_enterSuppressRegion (fileloc loc
)
391 if (gc
.insuppressregion
)
393 gc
.insuppressregion
= FALSE
; /* get this msg! */
395 ("%q: New ignore errors region entered while in ignore errors region",
396 fileloc_unparse (loc
)));
399 gc
.insuppressregion
= TRUE
;
400 (void) flagMarkerList_add (gc
.markers
, flagMarker_createIgnoreOn (loc
));
404 context_addFlagMarker (flagcode code
, ynm set
, fileloc loc
)
406 (void) flagMarkerList_add (gc
.markers
,
407 flagMarker_createLocalSet (code
, set
, loc
));
411 context_enterSuppressLine (int count
, fileloc loc
)
413 if (context_processingMacros ())
418 if (flagMarkerList_add
420 flagMarker_createIgnoreCount (count
, loc
)))
422 fileloc nextline
= fileloc_copy (loc
);
423 fileloc_nextLine (nextline
);
424 fileloc_setColumn (nextline
, 0);
426 check (flagMarkerList_add (gc
.markers
,
427 flagMarker_createIgnoreOff (nextline
)));
428 fileloc_free (nextline
);
432 void context_checkSuppressCounts (void)
434 if (context_getFlag (FLG_SUPCOUNTS
))
436 flagMarkerList_checkSuppressCounts (gc
.markers
);
440 void context_incLineno (void)
447 context_exitSuppressRegion (fileloc loc
)
449 if (!gc
.insuppressregion
)
453 message ("End ignore errors in region while not ignoring errors"),
457 gc
.insuppressregion
= FALSE
;
458 (void) flagMarkerList_add (gc
.markers
, flagMarker_createIgnoreOff (loc
));
462 context_enterMTfile (void)
468 context_exitMTfile (void)
470 llassert (gc
.kind
== CX_MT
);
475 context_enterLCLfile (void)
478 gc
.facct
= typeIdSet_emptySet ();
482 addModuleAccess (/*@only@*/ cstring fname
, typeIdSet mods
)
486 for (i
= 0; i
< gc
.nmods
; i
++)
488 if (cstring_equal (gc
.moduleaccess
[i
].file
, fname
))
490 gc
.moduleaccess
[i
].daccess
= typeIdSet_union (gc
.moduleaccess
[i
].daccess
, mods
);
491 cstring_free (fname
);
496 if (gc
.nmods
== gc
.maxmods
)
500 gc
.maxmods
= gc
.maxmods
+ DEFAULTMAXMODS
;
501 oldmods
= gc
.moduleaccess
;
503 gc
.moduleaccess
= (maccesst
*) dmalloc (sizeof (*gc
.moduleaccess
) * (gc
.maxmods
));
505 for (i
= 0; i
< gc
.nmods
; i
++)
507 gc
.moduleaccess
[i
] = oldmods
[i
];
513 gc
.moduleaccess
[gc
.nmods
].file
= fname
;
514 gc
.moduleaccess
[gc
.nmods
].daccess
= mods
;
520 insertModuleAccess (cstring fname
, typeId t
)
524 for (i
= 0; i
< gc
.nmods
; i
++)
526 if (cstring_equal (gc
.moduleaccess
[i
].file
, fname
))
528 gc
.moduleaccess
[i
].daccess
= typeIdSet_insert (gc
.moduleaccess
[i
].daccess
, t
);
533 addModuleAccess (cstring_copy (fname
), typeIdSet_single (t
));
537 context_exitLCLfile (void)
539 if (gc
.kind
!= CX_LCLLIB
)
542 fileLib_withoutExtension (fileTable_fileName (currentFile ()), LCL_EXTENSION
);
544 addModuleAccess (fileLib_removePath (lclname
), gc
.facct
);
545 cstring_free (lclname
);
549 gc
.facct
= typeIdSet_emptySet ();
553 context_dumpModuleAccess (FILE *fout
)
557 for (i
= 0; i
< gc
.nmods
; i
++)
559 cstring td
= typeIdSet_dump (gc
.moduleaccess
[i
].daccess
);
561 fprintf (fout
, "%s#%s@\n",
562 cstring_toCharsSafe (gc
.moduleaccess
[i
].file
),
563 cstring_toCharsSafe (td
));
569 bool context_usingPosixLibrary (void)
571 return (gc
.library
== FLG_POSIXLIB
572 || gc
.library
== FLG_POSIXSTRICTLIB
573 || gc
.library
== FLG_UNIXLIB
574 || gc
.library
== FLG_UNIXSTRICTLIB
);
577 bool context_usingStdLibrary (void)
579 return (gc
.library
!= FLG_NOLIB
);
582 flagcode
context_getLibrary (void)
587 void context_setLibrary (flagcode code
)
591 /* what if these any of these flags has already been explicitly set?
592 * we're changing them without any warning to the user ... */
593 gc
.flags
[FLG_SKIPSTDHEADERS
] = context_usingStdLibrary ();
594 gc
.flags
[FLG_SKIPPOSIXHEADERS
] = context_usingPosixLibrary ();
597 /*@observer@*/ cstring
context_selectedLibrary (void)
602 return cstring_makeLiteralTemp (LLSTDLIBS_NAME
);
603 case FLG_STDSTRICTLIB
:
604 return cstring_makeLiteralTemp (LLSTDSTRICTLIBS_NAME
);
606 return cstring_makeLiteralTemp (LLPOSIXLIBS_NAME
);
607 case FLG_POSIXSTRICTLIB
:
608 return cstring_makeLiteralTemp (LLPOSIXSTRICTLIBS_NAME
);
610 return cstring_makeLiteralTemp (LLUNIXLIBS_NAME
);
611 case FLG_UNIXSTRICTLIB
:
612 return cstring_makeLiteralTemp (LLUNIXSTRICTLIBS_NAME
);
619 context_loadModuleAccess (FILE *in
)
621 char *s
= mstring_create (MAX_DUMP_LINE_LENGTH
);
623 char *name
= mstring_create (MAX_NAME_LENGTH
);
627 while ((reader_readLine (in
, s
, MAX_DUMP_LINE_LENGTH
) != NULL
)
633 while (s
!= NULL
&& *s
!= ';' && *s
!= '\0')
637 while (*s
!= '#' && *s
!= '\0')
646 llcontbug (message ("context_loadModuleAccess: bad library line: %s\n",
647 cstring_fromChars (s
)));
653 addModuleAccess (cstring_copy (cstring_fromChars (oname
)),
654 typeIdSet_undump (&s
));
656 (void) reader_readLine (in
, s
, MAX_DUMP_LINE_LENGTH
);
657 llassert (s
!= lasts
);
665 typeIdSet
context_fileAccessTypes (void)
671 context_resetModeFlags (void)
675 if (flagcode_isModeFlag (code
))
677 context_setFlag (code
, FALSE
, g_currentloc
);
685 ** Set all flags to FALSE, except for a few which are
688 ** Set all values and strings to appropriate defaults.
689 ** Set all counters to 0.
693 conext_resetAllCounters (void)
697 for (i
= 0; i
< NUMVALUEFLAGS
; i
++)
704 context_resetAllFlags (void)
706 DPRINTF (("******** Reset all flags"));
710 gc
.flags
[code
] = FALSE
;
712 if (flagcode_hasNumber (code
))
716 /*@-loopswitchbreak@*/
720 val
= DEFAULT_LIMIT
; break;
722 val
= DEFAULT_BUGSLIMIT
; break;
724 val
= DEFAULT_LINELEN
; break;
725 case FLG_INDENTSPACES
:
726 val
= DEFAULT_INDENTSPACES
; break;
727 case FLG_LOCINDENTSPACES
:
728 val
= DEFAULT_LOCINDENTSPACES
; break;
729 case FLG_EXTERNALNAMELEN
:
730 val
= ISO99_EXTERNALNAMELEN
; break;
731 case FLG_INTERNALNAMELEN
:
732 val
= ISO99_INTERNALNAMELEN
; break;
733 case FLG_COMMENTCHAR
:
734 val
= (int) DEFAULT_COMMENTCHAR
; break;
735 case FLG_CONTROLNESTDEPTH
:
736 val
= (int) ISO99_CONTROLNESTDEPTH
; break;
737 case FLG_STRINGLITERALLEN
:
738 val
= (int) ISO99_STRINGLITERALLEN
; break;
739 case FLG_INCLUDENEST
:
740 val
= (int) ISO99_INCLUDENEST
; break;
741 case FLG_NUMSTRUCTFIELDS
:
742 val
= (int) ISO99_NUMSTRUCTFIELDS
; break;
743 case FLG_NUMENUMMEMBERS
:
744 val
= (int) ISO99_NUMENUMMEMBERS
; break;
749 llbug (message ("Bad value flag: %s", flagcode_unparse (code
)));
751 /*@=loopswitchbreak@*/
753 DPRINTF (("Set value: [%s] / %d", flagcode_unparse (code
), val
));
754 context_setValue (code
, val
);
755 DPRINTF (("Set value: [%s] / %d", flagcode_unparse (code
), context_getValue (code
)));
756 llassert (context_getValue (code
) == val
);
758 else if (flagcode_hasChar (code
))
760 llassert (code
== FLG_COMMENTCHAR
);
761 context_setCommentMarkerChar (DEFAULT_COMMENTCHAR
);
763 else if (flagcode_hasString (code
))
765 cstring val
= cstring_undefined
;
768 { /*@-loopswitchbreak@*/
771 cstring larchpath
= cstring_makeLiteralTemp (getenv (LARCH_PATH
));
773 if (cstring_isDefined (larchpath
))
775 val
= cstring_copy (larchpath
);
779 val
= osd_pathListConcat (".", LARCHDIR
);
784 case FLG_LCLIMPORTDIR
:
786 cstring lclimpordir
= cstring_makeLiteralTemp (getenv (LCLIMPORTDIR
));
788 if (cstring_isDefined (lclimpordir
))
790 val
= cstring_copy (lclimpordir
);
794 val
= osd_pathListConcat (".", LCLDIR
);
800 val
= osd_getTempDir(); break;
802 val
= cstring_makeLiteral (DEFAULT_BOOLTYPE
); break;
804 val
= cstring_makeLiteral ("false"); break;
806 val
= cstring_makeLiteral ("true"); break;
807 case FLG_MACROVARPREFIX
:
808 val
= cstring_makeLiteral ("m_"); break;
810 val
= cstring_makeLiteral (DEFAULT_SYSTEMDIRS
); break;
813 } /*@=loopswitchbreak@*/
815 context_setString (code
, val
);
819 ; /* nothing to set */
824 ** These flags are true by default.
827 /* eventually, move this into flags.def */
829 gc
.flags
[FLG_STREAMOVERWRITE
] = TRUE
;
830 gc
.flags
[FLG_OBVIOUSLOOPEXEC
] = TRUE
;
831 gc
.flags
[FLG_MODIFIES
] = TRUE
;
832 gc
.flags
[FLG_NESTCOMMENT
] = TRUE
;
833 gc
.flags
[FLG_GLOBALS
] = TRUE
;
834 gc
.flags
[FLG_FULLINITBLOCK
] = TRUE
;
835 gc
.flags
[FLG_INITSIZE
] = TRUE
;
836 gc
.flags
[FLG_INITALLELEMENTS
] = TRUE
;
837 gc
.flags
[FLG_NULLINIT
] = TRUE
;
839 gc
.flags
[FLG_STRINGLITTOOLONG
] = TRUE
;
840 gc
.flags
[FLG_MACROCONSTDIST
] = TRUE
;
841 gc
.flags
[FLG_LIKELYBOOL
] = TRUE
;
842 gc
.flags
[FLG_ZEROPTR
] = TRUE
;
843 gc
.flags
[FLG_NUMLITERAL
] = TRUE
;
844 gc
.flags
[FLG_DUPLICATEQUALS
] = TRUE
;
845 gc
.flags
[FLG_SKIPSTDHEADERS
] = TRUE
;
846 gc
.flags
[FLG_SKIPPOSIXHEADERS
] = FALSE
;
847 gc
.flags
[FLG_SYSTEMDIREXPAND
] = TRUE
;
848 gc
.flags
[FLG_UNRECOGCOMMENTS
] = TRUE
;
849 gc
.flags
[FLG_UNRECOGFLAGCOMMENTS
] = TRUE
;
850 gc
.flags
[FLG_CASTFCNPTR
] = TRUE
;
851 gc
.flags
[FLG_DOLCS
] = TRUE
;
852 gc
.flags
[FLG_USEVARARGS
] = TRUE
;
853 gc
.flags
[FLG_MAINTYPE
] = TRUE
;
854 gc
.flags
[FLG_SPECMACROS
] = TRUE
;
855 gc
.flags
[FLG_REDEF
] = TRUE
;
856 gc
.flags
[FLG_MACRONEXTLINE
] = TRUE
;
858 gc
.flags
[FLG_SIZEOFFORMALARRAY
] = TRUE
;
859 gc
.flags
[FLG_FIXEDFORMALARRAY
] = TRUE
;
861 gc
.flags
[FLG_UNRECOGDIRECTIVE
] = TRUE
;
862 gc
.flags
[FLG_WARNUSE
] = TRUE
;
863 gc
.flags
[FLG_PREDASSIGN
] = TRUE
;
864 gc
.flags
[FLG_MODOBSERVER
] = TRUE
;
865 gc
.flags
[FLG_MACROVARPREFIXEXCLUDE
] = TRUE
;
866 gc
.flags
[FLG_EXTERNALNAMECASEINSENSITIVE
] = TRUE
;
868 gc
.flags
[FLG_PARAMIMPTEMP
] = TRUE
;
869 gc
.flags
[FLG_RETIMPONLY
] = TRUE
;
870 gc
.flags
[FLG_GLOBIMPONLY
] = TRUE
;
871 gc
.flags
[FLG_STRUCTIMPONLY
] = TRUE
;
872 gc
.flags
[FLG_PREPROC
] = TRUE
;
873 gc
.flags
[FLG_NAMECHECKS
] = TRUE
;
874 gc
.flags
[FLG_FORMATCODE
] = TRUE
;
875 gc
.flags
[FLG_FORMATTYPE
] = TRUE
;
876 gc
.flags
[FLG_BADFLAG
] = TRUE
;
877 gc
.flags
[FLG_WARNFLAGS
] = TRUE
;
878 gc
.flags
[FLG_WARNRC
] = TRUE
;
879 gc
.flags
[FLG_FILEEXTENSIONS
] = TRUE
;
880 gc
.flags
[FLG_WARNUNIXLIB
] = FALSE
;
881 gc
.flags
[FLG_WARNPOSIX
] = TRUE
;
882 gc
.flags
[FLG_SHOWCOL
] = TRUE
;
883 gc
.flags
[FLG_SHOWDEEPHISTORY
] = FALSE
; /* TRUE; */
884 gc
.flags
[FLG_SHOWFUNC
] = TRUE
;
885 gc
.flags
[FLG_SUPCOUNTS
] = TRUE
;
886 gc
.flags
[FLG_HINTS
] = TRUE
;
887 gc
.flags
[FLG_SYNTAX
] = TRUE
;
888 gc
.flags
[FLG_TYPE
] = TRUE
;
889 gc
.flags
[FLG_INCOMPLETETYPE
] = TRUE
;
890 gc
.flags
[FLG_ABSTRACT
] = TRUE
;
891 gc
.flags
[FLG_NUMABSTRACT
] = TRUE
;
892 gc
.flags
[FLG_ITERBALANCE
] = TRUE
;
893 gc
.flags
[FLG_ITERYIELD
] = TRUE
;
894 gc
.flags
[FLG_DUPLICATECASES
] = TRUE
;
895 gc
.flags
[FLG_ALWAYSEXITS
] = TRUE
;
896 gc
.flags
[FLG_EMPTYRETURN
] = TRUE
;
897 gc
.flags
[FLG_MACRORETURN
] = TRUE
;
898 gc
.flags
[FLG_UNRECOG
] = TRUE
;
899 gc
.flags
[FLG_SYSTEMUNRECOG
] = TRUE
;
900 gc
.flags
[FLG_LINTCOMMENTS
] = TRUE
;
901 gc
.flags
[FLG_ACCESSCZECH
] = TRUE
;
902 gc
.flags
[FLG_ACCESSMODULE
] = TRUE
;
903 gc
.flags
[FLG_ACCESSFILE
] = TRUE
;
904 gc
.flags
[FLG_MACROVARPREFIX
] = TRUE
;
906 gc
.flags
[FLG_ANNOTATIONERROR
] = TRUE
;
907 gc
.flags
[FLG_COMMENTERROR
] = TRUE
;
910 ** Changed for version 2.4.
913 gc
.flags
[FLG_GNUEXTENSIONS
] = TRUE
;
919 /* commenting ou until some output issues are fixed */
920 gc
.flags
[FLG_ORCONSTRAINT
] = TRUE
;
922 gc
.flags
[FLG_CONSTRAINTLOCATION
] = TRUE
;
925 gc
.flags
[FLG_WARNSYSFILES
] = TRUE
;
928 ** On by default for Win32, but not Unix
931 # if defined (WIN32) || defined (OS2)
932 gc
.flags
[FLG_PARENFILEFORMAT
] = TRUE
;
933 gc
.flags
[FLG_CASEINSENSITIVEFILENAMES
] = TRUE
;
938 ** C is way-lame, and you can initialize an array to a constant except where
939 ** it is declared. Hence, a macro is used to set the modeflags.
943 # define SETFLAGS() \
944 { int i = 0; while (modeflags[i] != INVALID_FLAG) { \
945 if (!flagcode_isModeFlag (modeflags[i])) \
946 { llbug (message ("not a mode flag: %s", \
947 flagcode_unparse (modeflags[i]))); } \
948 else { context_setFlag (modeflags[i], TRUE, g_currentloc); } i++; }}
951 context_setModeAux (cstring s
, bool warn
)
953 intSet setflags
= intSet_new ();
957 if (flagcode_isModeFlag (code
))
959 if (gc
.setGlobally
[code
])
961 (void) intSet_insert (setflags
, (int) code
);
966 if (!intSet_isEmpty (setflags
))
968 cstring rflags
= cstring_undefined
;
971 intSet_elements (setflags
, el
)
973 if (cstring_isUndefined (rflags
))
975 rflags
= cstring_copy (flagcode_unparse ((flagcode
) (el
)));
979 rflags
= message ("%q, %s", rflags
,
980 flagcode_unparse ((flagcode
) el
));
984 if (num
> 4 && intSet_size (setflags
) > 6)
986 rflags
= message ("%q, (%d others) ...", rflags
,
987 intSet_size (setflags
) - num
);
990 } end_intSet_elements
;
994 voptgenerror (FLG_WARNFLAGS
,
995 message ("Setting mode %s after setting mode flags will "
996 "override set values of flags: %s",
1001 cstring_free (rflags
);
1004 intSet_free (setflags
);
1006 context_resetModeFlags ();
1008 if (cstring_equalLit (s
, "standard"))
1010 flagcode modeflags
[] =
1012 FLG_ENUMINT
, FLG_MACROMATCHNAME
,
1013 FLG_STRINGLITNOROOM
,
1014 FLG_STRINGLITNOROOMFINALNULL
,
1015 FLG_MACROUNDEF
, FLG_RELAXQUALS
,
1016 FLG_USEALLGLOBS
, FLG_CHECKSTRICTGLOBALS
,
1017 FLG_CHECKSTRICTGLOBALIAS
,
1018 FLG_CHECKEDGLOBALIAS
,
1019 FLG_CHECKMODGLOBALIAS
,
1020 FLG_PREDBOOLOTHERS
, FLG_PREDBOOLINT
,
1021 FLG_UNSIGNEDCOMPARE
,
1022 FLG_PARAMUNUSED
, FLG_VARUNUSED
, FLG_FUNCUNUSED
,
1024 FLG_ABSTRACTCOMPARE
,
1025 FLG_CONSTUNUSED
, FLG_ENUMMEMUNUSED
, FLG_FIELDUNUSED
,
1026 FLG_PTRNUMCOMPARE
, FLG_BOOLCOMPARE
, FLG_UNSIGNEDCOMPARE
,
1027 FLG_MUTREP
, FLG_NOEFFECT
, FLG_IMPTYPE
,
1028 FLG_RETVALOTHER
, FLG_RETVALBOOL
, FLG_RETVALINT
,
1029 FLG_SPECUNDEF
, FLG_INCONDEFS
, FLG_INCONDEFSLIB
, FLG_MISPLACEDSHAREQUAL
,
1032 FLG_MACROPARAMS
, FLG_MACROASSIGN
, FLG_SEFPARAMS
,
1033 FLG_MACROSTMT
, FLG_MACROPARENS
,
1036 FLG_MACROREDEF
, FLG_INFLOOPS
, FLG_UNREACHABLE
,
1037 FLG_NORETURN
, FLG_CASEBREAK
, FLG_MISSCASE
, FLG_USEDEF
,
1043 /* memchecks flags */
1045 FLG_NULLSTATE
, FLG_NULLASSIGN
,
1046 FLG_NULLPASS
, FLG_NULLRET
,
1049 FLG_COMPDEF
, FLG_COMPMEMPASS
, FLG_UNIONDEF
,
1052 /* memtrans flags */
1068 FLG_NUMABSTRACTCAST
,
1071 FLG_USERELEASED
, FLG_ALIASUNIQUE
, FLG_MAYALIASUNIQUE
,
1074 FLG_MUSTDEFINE
, FLG_GLOBSTATE
,
1075 FLG_COMPDESTROY
, FLG_MUSTNOTALIAS
,
1078 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1079 FLG_EVALORDER
, FLG_SHADOW
, FLG_READONLYSTRINGS
,
1081 FLG_IMPCHECKEDSPECGLOBALS
,
1082 FLG_MODGLOBS
, FLG_WARNLINTCOMMENTS
,
1083 FLG_IFEMPTY
, FLG_REALCOMPARE
,
1084 FLG_BOOLOPS
, FLG_PTRNEGATE
,
1086 FLG_SHIFTIMPLEMENTATION
,
1087 FLG_BUFFEROVERFLOWHIGH
,
1094 else if (cstring_equalLit (s
, "weak"))
1096 flagcode modeflags
[] =
1098 FLG_BOOLINT
, FLG_CHARINT
, FLG_FLOATDOUBLE
, FLG_LONGINT
, FLG_SHORTINT
,
1099 FLG_ENUMINT
, FLG_RELAXQUALS
, FLG_FORWARDDECL
,
1100 FLG_CHARINDEX
, FLG_NUMABSTRACTINDEX
, FLG_ABSTVOIDP
, FLG_USEALLGLOBS
,
1101 FLG_CHARUNSIGNEDCHAR
,
1104 FLG_VARUNUSED
, FLG_FUNCUNUSED
,
1106 FLG_CHECKSTRICTGLOBALS
, FLG_MACROMATCHNAME
,
1109 FLG_BUFFEROVERFLOWHIGH
,
1110 FLG_RETSTACK
, FLG_PTRNEGATE
,
1111 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1112 FLG_LONGUNSIGNEDINTEGRAL
,
1113 FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL
,
1117 FLG_BUFFEROVERFLOWHIGH
,
1118 FLG_STRINGLITNOROOM
,
1119 FLG_STRINGLITNOROOMFINALNULL
,
1125 else if (cstring_equalLit (s
, "checks"))
1127 flagcode modeflags
[] =
1129 FLG_EXPORTLOCAL
, FLG_IMPTYPE
,
1130 FLG_NUMABSTRACTCAST
,
1131 FLG_ABSTRACTCOMPARE
,
1132 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1133 FLG_CHECKSTRICTGLOBALIAS
,
1134 FLG_CHECKEDGLOBALIAS
,
1135 FLG_CHECKMODGLOBALIAS
,
1136 FLG_UNCHECKEDGLOBALIAS
,
1138 FLG_STRINGLITNOROOM
,
1139 FLG_STRINGLITNOROOMFINALNULL
,
1140 FLG_STRINGLITSMALLER
,
1141 FLG_EXITARG
, FLG_PTRNUMCOMPARE
,
1142 FLG_BOOLCOMPARE
, FLG_UNSIGNEDCOMPARE
,
1143 FLG_MACROUNDEF
, FLG_MUSTMOD
, FLG_ALLGLOBALS
,
1144 FLG_PREDBOOLOTHERS
, FLG_PREDBOOLPTR
, FLG_PREDBOOLINT
,
1145 FLG_USEALLGLOBS
, FLG_MUTREP
, FLG_RETALIAS
,
1146 FLG_RETEXPOSE
, FLG_ASSIGNEXPOSE
, FLG_CASTEXPOSE
,
1147 FLG_FUNCUNUSED
, FLG_GLOBALSIMPMODIFIESNOTHING
,
1148 FLG_TYPEUNUSED
, FLG_FIELDUNUSED
, FLG_PARAMUNUSED
, FLG_VARUNUSED
,
1149 FLG_CONSTUNUSED
, FLG_ENUMMEMUNUSED
,
1150 FLG_NOEFFECT
, FLG_EXPORTHEADER
, FLG_EXPORTHEADERVAR
,
1151 FLG_RETVALOTHER
, FLG_RETVALBOOL
, FLG_RETVALINT
,
1152 FLG_SPECUNDEF
, FLG_IMPCHECKMODINTERNALS
,
1153 FLG_DECLUNDEF
, FLG_INCONDEFS
, FLG_INCONDEFSLIB
,
1154 FLG_MISPLACEDSHAREQUAL
, FLG_REDUNDANTSHAREQUAL
,
1155 FLG_NUMABSTRACTPRINT
,
1162 FLG_SEFPARAMS
, FLG_SEFUNSPEC
, FLG_MACROSTMT
, FLG_MACROPARENS
,
1166 FLG_INFLOOPS
, FLG_INFLOOPSUNCON
,
1168 FLG_NORETURN
, FLG_CASEBREAK
, FLG_MISSCASE
,
1169 FLG_EVALORDER
, FLG_USEDEF
,
1172 /* warn use flags */
1173 FLG_MULTITHREADED
, FLG_PORTABILITY
, FLG_SUPERUSER
, FLG_IMPLEMENTATIONOPTIONAL
,
1174 FLG_BUFFEROVERFLOWHIGH
,
1176 /* memchecks flags */
1178 FLG_NULLSTATE
, FLG_NULLDEREF
, FLG_NULLASSIGN
,
1179 FLG_NULLPASS
, FLG_NULLRET
,
1182 FLG_COMPDEF
, FLG_COMPMEMPASS
, FLG_UNIONDEF
, FLG_RETSTACK
,
1184 /* memtrans flags */
1198 FLG_STATICINITTRANS
,
1199 FLG_UNKNOWNINITTRANS
,
1202 FLG_ONLYUNQGLOBALTRANS
,
1203 FLG_USERELEASED
, FLG_ALIASUNIQUE
, FLG_MAYALIASUNIQUE
,
1206 FLG_MUSTDEFINE
, FLG_GLOBSTATE
,
1207 FLG_COMPDESTROY
, FLG_MUSTNOTALIAS
,
1210 FLG_NULLPOINTERARITH
,
1211 FLG_SHADOW
, FLG_DEPARRAYS
,
1212 FLG_REDECL
, FLG_READONLYSTRINGS
, FLG_READONLYTRANS
,
1213 FLG_LOOPLOOPBREAK
, FLG_SWITCHLOOPBREAK
, FLG_MODGLOBS
,
1214 FLG_CHECKSTRICTGLOBALS
, FLG_IMPCHECKEDSPECGLOBALS
,
1215 FLG_MACROMATCHNAME
, FLG_WARNLINTCOMMENTS
,
1216 FLG_INCLUDENEST
, FLG_ISORESERVED
, FLG_CPPNAMES
,
1217 FLG_NOPARAMS
, FLG_IFEMPTY
, FLG_WHILEEMPTY
, FLG_REALCOMPARE
, FLG_REALRELATECOMPARE
,
1218 FLG_BOOLOPS
, FLG_SHIFTNEGATIVE
,
1219 FLG_SHIFTIMPLEMENTATION
,
1220 FLG_BUFFEROVERFLOWHIGH
, FLG_BUFFEROVERFLOW
,
1225 else if (cstring_equalLit (s
, "strict"))
1227 flagcode modeflags
[] =
1229 FLG_ABSTRACTCOMPARE
,
1230 FLG_CHECKSTRICTGLOBALIAS
,
1231 FLG_NUMABSTRACTCAST
,
1232 FLG_CHECKEDGLOBALIAS
,
1233 FLG_CHECKMODGLOBALIAS
,
1234 FLG_UNCHECKEDGLOBALIAS
,
1238 FLG_NUMABSTRACTPRINT
,
1239 FLG_STRINGLITNOROOM
,
1240 FLG_STRINGLITNOROOMFINALNULL
,
1241 FLG_STRINGLITSMALLER
,
1242 FLG_STATETRANSFER
, FLG_STATEMERGE
,
1243 FLG_MACROUNDEF
, FLG_MUTREP
, FLG_MUSTMOD
,
1244 FLG_ALLGLOBALS
, FLG_IMPTYPE
,
1245 FLG_MODNOMODS
, FLG_MODGLOBSUNSPEC
, FLG_MODSTRICTGLOBSUNSPEC
,
1246 FLG_GLOBUNSPEC
, FLG_SIZEOFTYPE
,
1247 FLG_EXPORTHEADER
, FLG_EXPORTHEADERVAR
,
1248 FLG_NOPARAMS
, FLG_OLDSTYLE
, FLG_EXITARG
,
1251 FLG_ONLYUNQGLOBALTRANS
,
1252 FLG_GLOBALSIMPMODIFIESNOTHING
,
1253 FLG_PREDBOOLOTHERS
, FLG_PREDBOOLPTR
, FLG_PREDBOOLINT
,
1254 FLG_INTERNALGLOBS
, FLG_INTERNALGLOBSNOGLOBS
,
1255 FLG_USEALLGLOBS
, FLG_RETALIAS
,
1256 FLG_MODGLOBS
, FLG_MODGLOBSUNSPEC
, FLG_MODGLOBSUNCHECKED
,
1257 FLG_RETEXPOSE
, FLG_ASSIGNEXPOSE
, FLG_CASTEXPOSE
,
1258 FLG_NOEFFECTUNCON
, FLG_EVALORDERUNCON
,
1260 FLG_EXPORTITER
, FLG_EXPORTCONST
,
1261 FLG_TYPEUNUSED
, FLG_FIELDUNUSED
, FLG_PARAMUNUSED
, FLG_TOPUNUSED
,
1262 FLG_CONSTUNUSED
, FLG_ENUMMEMUNUSED
,
1264 FLG_NULLPOINTERARITH
, FLG_POINTERARITH
,
1266 FLG_BOOLCOMPARE
, FLG_UNSIGNEDCOMPARE
,
1267 FLG_NOEFFECT
, FLG_RETVALINT
, FLG_RETVALBOOL
, FLG_RETVALOTHER
,
1268 FLG_ISORESERVED
, FLG_ISORESERVEDLOCAL
, FLG_CPPNAMES
,
1269 FLG_RETVALBOOL
, FLG_RETVALINT
, FLG_SPECUNDEF
,
1270 FLG_DECLUNDEF
, FLG_STRICTOPS
, FLG_INCONDEFS
,
1271 FLG_MISPLACEDSHAREQUAL
, FLG_REDUNDANTSHAREQUAL
,
1272 FLG_INCONDEFSLIB
, FLG_MATCHFIELDS
, FLG_EXPORTMACRO
, FLG_EXPORTVAR
,
1273 FLG_EXPORTFCN
, FLG_EXPORTTYPE
, FLG_EXPORTLOCAL
, FLG_MACROPARAMS
,
1275 FLG_SEFPARAMS
, FLG_SEFUNSPEC
, FLG_MACROSTMT
, FLG_MACROPARENS
,
1278 FLG_MACROREDEF
, FLG_MACROEMPTY
,
1279 FLG_INFLOOPS
, FLG_INFLOOPSUNCON
,
1281 FLG_NORETURN
, FLG_CASEBREAK
, FLG_MISSCASE
, FLG_USEDEF
,
1283 FLG_MODUNCON
, FLG_MODUNCONNOMODS
, FLG_MODINTERNALSTRICT
,
1284 FLG_MODOBSERVERUNCON
,
1289 /* warn use flags */
1290 FLG_MULTITHREADED
, FLG_PORTABILITY
, FLG_SUPERUSER
, FLG_IMPLEMENTATIONOPTIONAL
,
1291 FLG_BUFFEROVERFLOWHIGH
,
1292 FLG_BUFFEROVERFLOW
, FLG_TOCTOU
,
1294 /* memchecks flags */
1295 FLG_NULLSTATE
, FLG_NULLDEREF
, FLG_NULLASSIGN
,
1296 FLG_NULLPASS
, FLG_NULLRET
,
1298 FLG_COMPDEF
, FLG_COMPMEMPASS
, FLG_UNIONDEF
,
1300 /* memory checking flags */
1301 FLG_BOUNDSREAD
, FLG_BOUNDSWRITE
,
1302 FLG_LIKELYBOUNDSREAD
, FLG_LIKELYBOUNDSWRITE
,
1305 /* memtrans flags */
1321 FLG_STATICINITTRANS
,
1322 FLG_UNKNOWNINITTRANS
,
1324 FLG_USERELEASED
, FLG_ALIASUNIQUE
, FLG_MAYALIASUNIQUE
,
1327 FLG_MUSTDEFINE
, FLG_GLOBSTATE
,
1328 FLG_COMPDESTROY
, FLG_MUSTNOTALIAS
,
1332 FLG_DECLPARAMNAME
, FLG_DECLPARAMMATCH
,
1334 FLG_SHADOW
, FLG_DEPARRAYS
,
1335 FLG_STRICTDESTROY
, FLG_STRICTUSERELEASED
, FLG_STRICTBRANCHSTATE
,
1336 FLG_REDECL
, FLG_READONLYSTRINGS
, FLG_READONLYTRANS
,
1337 FLG_LOOPLOOPBREAK
, FLG_LOOPSWITCHBREAK
, FLG_SWITCHLOOPBREAK
,
1338 FLG_SWITCHSWITCHBREAK
, FLG_LOOPLOOPCONTINUE
,
1339 FLG_CHECKSTRICTGLOBALS
, FLG_IMPCHECKEDSPECGLOBALS
,
1340 FLG_ALLGLOBALS
, FLG_IMPCHECKEDSTRICTGLOBALS
,
1341 FLG_IMPCHECKEDSTRICTSTATICS
,
1342 FLG_IMPCHECKEDSTRICTSPECGLOBALS
,
1343 FLG_IMPCHECKMODINTERNALS
,
1344 FLG_WARNMISSINGGLOBALS
, FLG_WARNMISSINGGLOBALSNOGLOBS
,
1345 FLG_WARNLINTCOMMENTS
, FLG_ISORESERVEDLOCAL
,
1346 FLG_INCLUDENEST
, FLG_STRINGLITERALLEN
,
1347 FLG_NUMSTRUCTFIELDS
, FLG_NUMENUMMEMBERS
,
1348 FLG_CONTROLNESTDEPTH
,
1349 FLG_FORBLOCK
, FLG_WHILEBLOCK
,
1350 FLG_FOREMPTY
, FLG_WHILEEMPTY
,
1351 FLG_IFEMPTY
, FLG_IFBLOCK
,
1353 FLG_REALCOMPARE
, FLG_BOOLOPS
, FLG_REALRELATECOMPARE
,
1354 FLG_SYSTEMDIRERRORS
, FLG_UNUSEDSPECIAL
,
1357 FLG_SHIFTIMPLEMENTATION
,
1359 FLG_BUFFEROVERFLOWHIGH
, FLG_BUFFEROVERFLOW
,
1367 llcontbug (message ("context_setMode: bad mode: %s", s
));
1372 context_setMode (cstring s
)
1374 context_setModeAux (s
, TRUE
);
1378 context_setModeNoWarn (cstring s
)
1380 context_setModeAux (s
, FALSE
);
1385 context_isSystemDir (cstring dir
)
1387 return osd_pathPrefixInPathList (dir
, context_getString (FLG_SYSTEMDIRS
));
1391 context_addFileAccessType (typeId t
)
1395 if (context_inFunctionLike ())
1397 gc
.acct
= typeIdSet_insert (gc
.acct
, t
);
1400 gc
.facct
= typeIdSet_insert (gc
.facct
, t
);
1402 base
= fileloc_getBase (g_currentloc
);
1403 insertModuleAccess (base
, t
);
1404 DPRINTF (("Add file access: %s / %s", typeIdSet_unparse (gc
.facct
),
1405 typeIdSet_unparse (gc
.acct
)));
1409 context_removeFileAccessType (typeId t
)
1411 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
1412 || gc
.kind
== CX_UNKNOWNMACRO
)
1414 gc
.acct
= typeIdSet_removeFresh (gc
.acct
, t
);
1417 gc
.facct
= typeIdSet_removeFresh (gc
.facct
, t
);
1418 gc
.nacct
= typeIdSet_insert (gc
.nacct
, t
);
1421 void context_enterFunctionHeader (void)
1423 if (context_getFlag (FLG_GRAMMAR
))
1425 lldiagmsg (message ("Enter function header: %q", context_unparse ()));
1428 if (gc
.kind
!= CX_GLOBAL
)
1430 llparseerror (cstring_makeLiteral
1431 ("Likely parse error. Function header outside global context."));
1434 DPRINTF (("Enter function header!"));
1435 gc
.inFunctionHeader
= TRUE
;
1438 void context_exitFunctionHeader (void)
1440 if (context_getFlag (FLG_GRAMMAR
))
1442 lldiagmsg (message ("Exit function header: %q", context_unparse ()));
1445 DPRINTF (("Exit function header!"));
1446 gc
.inFunctionHeader
= FALSE
;
1449 bool context_inFunctionHeader (void)
1451 return (gc
.inFunctionHeader
);
1454 void context_enterFunctionDeclaration (uentry e
)
1456 if (context_getFlag (FLG_GRAMMAR
))
1458 lldiagmsg (message ("Enter function declaration: %q", context_unparse ()));
1461 DPRINTF (("Enter function decl"));
1462 llassert (gc
.savekind
== CX_ERROR
);
1463 gc
.savekind
= gc
.kind
;
1464 gc
.savecont
= gc
.cont
;
1465 gc
.kind
= CX_FCNDECLARATION
;
1469 void context_exitFunctionDeclaration (void)
1471 if (context_getFlag (FLG_GRAMMAR
))
1473 lldiagmsg (message ("Exit function declaration: %q", context_unparse ()));
1476 DPRINTF (("Exit function decl"));
1477 llassert (gc
.savekind
!= CX_ERROR
);
1478 llassert (gc
.kind
== CX_FCNDECLARATION
);
1479 gc
.kind
= gc
.savekind
;
1480 gc
.cont
= gc
.savecont
;
1482 gc
.savekind
= CX_ERROR
;
1484 if (context_getFlag (FLG_GRAMMAR
))
1486 lldiagmsg (message ("After exit function declaration: %q", context_unparse ()));
1491 bool context_inFunctionDeclaration (void)
1493 return (gc
.kind
== CX_FCNDECLARATION
);
1495 # endif /* DEADCODE */
1498 context_enterMacro (/*@observer@*/ uentry e
)
1500 context_enterFunction (e
);
1501 gc
.kind
= CX_MACROFCN
;
1505 context_enterUnknownMacro (/*@dependent@*/ uentry e
)
1507 llassert (uentry_isFunction (e
));
1508 context_enterFunction (e
);
1509 gc
.kind
= CX_UNKNOWNMACRO
;
1512 void context_enterAndClause (exprNode e
)
1514 DPRINTF (("enter and clause: %s", exprNode_unparse (e
)));
1515 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e
)));
1516 pushClause (ANDCLAUSE
);
1519 void context_enterOrClause (exprNode e
)
1521 usymtab_trueBranch (guardSet_invert (exprNode_getGuards (e
)));
1522 pushClause (ORCLAUSE
);
1525 bool context_inDeepLoop (void)
1527 bool inLoop
= FALSE
;
1529 clauseStack_elements (gc
.clauses
, el
)
1531 if (clause_isLoop (el
))
1540 } end_clauseStack_elements
;
1545 bool context_inDeepSwitch (void)
1547 bool inLoop
= FALSE
;
1549 clauseStack_elements (gc
.clauses
, el
)
1551 if (clause_isSwitch (el
))
1560 } end_clauseStack_elements
;
1565 bool context_inDeepLoopSwitch (void)
1567 bool inLoop
= FALSE
;
1569 clauseStack_elements (gc
.clauses
, el
)
1571 if (clause_isBreakable (el
))
1580 } end_clauseStack_elements
;
1585 clause
context_breakClause (void)
1587 clauseStack_elements (gc
.clauses
, el
)
1589 if (clause_isSwitch (el
))
1593 else if (clause_isLoop (el
))
1601 } end_clauseStack_elements
;
1606 clause
context_nextBreakClause (void)
1608 bool hasOne
= FALSE
;
1610 clauseStack_elements (gc
.clauses
, el
)
1612 if (clause_isBreakable (el
))
1623 } end_clauseStack_elements
;
1628 bool context_inConditional (void)
1630 clauseStack_elements (gc
.clauses
, el
)
1633 ** Should also include TRUECLAUSE and FALSECLAUSE, but need
1634 ** to distinguish if from ? for this
1637 if (clause_isBreakable (el
) && (el
!= DOWHILECLAUSE
))
1641 } end_clauseStack_elements
;
1646 void context_exitAndClause (exprNode pred
, exprNode tbranch
)
1648 context_setJustPopped ();
1650 llassert (gc
.inclause
== ANDCLAUSE
);
1652 usymtab_popAndBranch (pred
, tbranch
);
1653 clauseStack_pop (gc
.clauses
);
1654 gc
.inclause
= topClause (gc
.clauses
);
1657 void context_exitOrClause (exprNode pred
, exprNode tbranch
)
1659 context_setJustPopped ();
1661 llassert (gc
.inclause
== ORCLAUSE
);
1663 usymtab_popOrBranch (pred
, tbranch
);
1664 clauseStack_pop (gc
.clauses
);
1665 gc
.inclause
= topClause (gc
.clauses
);
1668 static void context_enterCondClauseAux (clause cl
)
1674 static void context_enterTrueAux (exprNode e
, clause cl
)
1677 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e
)));
1681 void context_enterIterClause (void)
1683 context_enterTrueAux (exprNode_undefined
, ITERCLAUSE
);
1686 void context_enterDoWhileClause (void)
1688 pushClause (DOWHILECLAUSE
);
1691 void context_enterWhileClause (exprNode e
)
1693 context_enterTrueAux (e
, WHILECLAUSE
);
1696 void context_enterForClause (exprNode e
)
1698 context_enterTrueAux (e
, FORCLAUSE
);
1701 void context_enterTrueClause (exprNode e
)
1703 context_enterTrueAux (e
, TRUECLAUSE
);
1706 void context_enterSwitch (exprNode e
)
1708 DPRINTF (("Enter switch: %s", exprNode_unparse (e
)));
1709 usymtab_switchBranch (e
);
1710 context_enterCondClauseAux (SWITCHCLAUSE
);
1713 void context_exitSwitch (exprNode e
, bool allpaths
)
1715 usymtab_exitSwitch (e
, allpaths
);
1717 while (clause_isCase (clauseStack_top (gc
.clauses
)))
1719 clauseStack_pop (gc
.clauses
);
1722 context_exitClauseSimp ();
1725 void context_enterCaseClause (exprNode e
)
1727 bool branch
= FALSE
;
1729 DPRINTF (("Enter case clause!"));
1731 branch
= usymtab_newCase (exprNode_undefined
, e
);
1735 context_enterCondClauseAux (CASECLAUSE
);
1739 static void context_enterFalseClauseAux (exprNode e
, clause cl
)
1742 usymtab_altBranch (guardSet_invert (exprNode_getGuards (e
)));
1744 clauseStack_switchTop (gc
.clauses
, cl
);
1747 void context_enterFalseClause (exprNode e
)
1749 context_enterFalseClauseAux (e
, FALSECLAUSE
);
1753 context_enterConstantMacro (/*@exposed@*/ /*@dependent@*/ uentry e
)
1755 gc
.kind
= CX_MACROCONST
;
1757 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1759 gc
.acct
= typeIdSet_subtract (typeIdSet_union (gc
.facct
, uentry_accessType (e
)),
1763 usymtab_enterScope ();
1764 sRef_enterFunctionScope ();
1766 gc
.globs
= globSet_undefined
;
1767 globSet_clear (gc
.globs_used
);
1768 gc
.mods
= sRefSet_undefined
;
1771 uentry
context_getHeader (void)
1773 if (!(context_inFunctionLike () || (gc
.kind
== CX_MACROCONST
)))
1775 llfatalbug (message ("context_getHeader: bad call: %q",
1776 context_unparse ()));
1779 return (gc
.cont
.fcn
);
1783 context_setFunctionDefined (fileloc loc
)
1787 case CX_UNKNOWNMACRO
:
1790 uentry_setFunctionDefined (gc
.cont
.fcn
, loc
);
1793 /* (not a bug because of parse errors) */
1799 context_enterFunction (/*@exposed@*/ uentry e
)
1801 gc
.kind
= CX_FUNCTION
;
1804 DPRINTF (("Enter function: %s", uentry_unparse (e
)));
1806 if (uentry_hasAccessType (e
))
1808 gc
.acct
= typeIdSet_subtract (typeIdSet_union (gc
.facct
, uentry_accessType (e
)),
1816 DPRINTF (("Enter function: %s / %s", uentry_unparse (e
),
1817 typeIdSet_unparse (gc
.acct
)));
1819 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1821 gc
.globs
= uentry_getGlobs (e
);
1822 globSet_clear (gc
.globs_used
);
1823 gc
.mods
= uentry_getMods (e
);
1825 usymtab_enterFunctionScope (e
);
1826 sRef_enterFunctionScope ();
1829 bool context_inOldStyleScope(void)
1831 return (gc
.kind
== CX_OLDSTYLESCOPE
);
1835 context_enterOldStyleScope (void)
1837 gc
.kind
= CX_OLDSTYLESCOPE
;
1838 DPRINTF (("Enter old style scope!"));
1839 usymtab_enterFunctionScope (uentry_undefined
);
1843 context_completeOldStyleFunction (uentry e
)
1845 llassert (gc
.kind
== CX_OLDSTYLESCOPE
);
1847 gc
.kind
= CX_FUNCTION
;
1850 DPRINTF (("Enter function: %s", uentry_unparse (e
)));
1852 if (uentry_hasAccessType (e
))
1854 gc
.acct
= typeIdSet_subtract (typeIdSet_union (gc
.facct
, uentry_accessType (e
)),
1862 DPRINTF (("Enter function: %s / %s", uentry_unparse (e
),
1863 typeIdSet_unparse (gc
.acct
)));
1865 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1867 if (!globSet_isEmpty (uentry_getGlobs (e
)))
1869 llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
1870 fileloc_unparse (g_currentloc
), uentry_unparse (e
)));
1873 gc
.showfunction
= context_getFlag (FLG_SHOWFUNC
);
1875 gc
.globs
= uentry_getGlobs (e
);
1876 globSet_clear (gc
.globs_used
);
1878 gc
.mods
= uentry_getMods (e
);
1880 if (!sRefSet_isEmpty (gc
.mods
))
1882 llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
1883 fileloc_unparse (g_currentloc
), uentry_unparse (e
)));
1886 sRef_enterFunctionScope ();
1889 static bool context_checkStrictGlobals (void)
1891 return (context_getFlag (FLG_CHECKSTRICTGLOBALS
));
1894 static bool context_hasGlobs (void)
1896 if (context_inFunctionLike ())
1898 return (uentry_hasGlobs (gc
.cont
.fcn
));
1906 static bool context_checkCheckedGlobals (void)
1908 return (context_getFlag (FLG_GLOBALS
)
1909 && (context_getFlag (FLG_GLOBUNSPEC
)
1910 || context_hasGlobs ()));
1913 static bool context_checkUnknownGlobals (void)
1915 /* should be uentry_hasGlobs ? */
1917 return (context_getFlag (FLG_ALLGLOBALS
)
1918 && (context_getFlag (FLG_GLOBUNSPEC
)
1919 || context_hasGlobs ()));
1922 static bool context_checkUncheckedGlobals (void)
1928 context_checkExport (uentry e
)
1930 if (!gc
.anyExports
) return FALSE
;
1932 if (uentry_isFunction (e
)
1933 || (uentry_isVariable (e
) && ctype_isFunction (uentry_getType (e
))))
1935 return context_maybeSet (FLG_EXPORTFCN
);
1937 else if (uentry_isExpandedMacro (e
))
1939 return context_maybeSet (FLG_EXPORTMACRO
);
1941 else if (uentry_isVariable (e
))
1943 return context_maybeSet (FLG_EXPORTVAR
);
1945 else if (uentry_isEitherConstant (e
))
1947 return context_maybeSet (FLG_EXPORTCONST
);
1949 else if (uentry_isIter (e
) || uentry_isEndIter (e
))
1951 return context_maybeSet (FLG_EXPORTITER
);
1953 else if (uentry_isDatatype (e
))
1955 return context_maybeSet (FLG_EXPORTTYPE
);
1964 context_checkGlobUse (uentry glob
)
1967 if (uentry_isCheckedStrict (glob
))
1969 return context_checkStrictGlobals ();
1971 else if (uentry_isChecked (glob
))
1973 return context_checkCheckedGlobals ();
1975 else if (uentry_isCheckedUnknown (glob
) || uentry_isCheckMod (glob
))
1977 return context_checkUnknownGlobals ();
1981 llassert (uentry_isUnchecked (glob
));
1983 return context_checkUncheckedGlobals ();
1988 context_checkAliasGlob (uentry glob
)
1990 if (uentry_isCheckedStrict (glob
))
1992 return gc
.flags
[FLG_CHECKSTRICTGLOBALIAS
];
1994 else if (uentry_isChecked (glob
))
1996 return gc
.flags
[FLG_CHECKEDGLOBALIAS
];
1998 else if (uentry_isCheckMod (glob
))
2000 return gc
.flags
[FLG_CHECKMODGLOBALIAS
];
2004 llassert (uentry_isUnchecked (glob
) || uentry_isCheckedUnknown (glob
));
2006 return gc
.flags
[FLG_UNCHECKEDGLOBALIAS
];
2010 bool context_checkInternalUse (void)
2012 if (context_hasGlobs ())
2014 return (gc
.flags
[FLG_INTERNALGLOBS
]);
2018 return (gc
.flags
[FLG_INTERNALGLOBSNOGLOBS
]);
2023 context_checkGlobMod (sRef el
)
2025 uentry ue
= sRef_getUentry (el
);
2027 /* no: llassert (sRef_isFileOrGlobalScope (el)); also check local statics */
2029 if (uentry_isCheckedModify (ue
)
2030 || (!uentry_isUnchecked (ue
) && (gc
.flags
[FLG_ALLGLOBALS
])))
2032 if (context_hasMods ())
2034 return (gc
.flags
[FLG_MODGLOBS
]);
2038 if (uentry_isCheckedStrict (ue
))
2040 return (gc
.flags
[FLG_MODGLOBSUNSPEC
]);
2044 return (gc
.flags
[FLG_MODSTRICTGLOBSUNSPEC
]);
2050 if (context_hasMods ())
2052 return (gc
.flags
[FLG_MODGLOBSUNCHECKED
]);
2062 context_usedGlobal (/*@exposed@*/ sRef el
)
2064 if (!globSet_member (gc
.globs_used
, el
))
2067 ** The first time a global is used in a function, we need
2068 ** to clear the derived sRefs, since they were set for the
2069 ** previous function.
2072 sRef_clearDerived (el
);
2073 gc
.globs_used
= globSet_insert (gc
.globs_used
, el
);
2077 /*@observer@*/ sRefSet
2078 context_modList (void)
2084 context_globAccess (sRef s
)
2086 llassert (sRef_isFileOrGlobalScope (s
) || sRef_isKindSpecial (s
));
2087 return (globSet_member (gc
.globs
, s
));
2091 context_hasAccess (typeId t
)
2093 if (context_inFunctionLike ())
2095 DPRINTF (("Access %d / %s",
2096 t
, typeIdSet_unparse (gc
.acct
)));
2097 return (typeIdSet_member (gc
.acct
, t
));
2101 return (context_hasFileAccess (t
));
2106 context_hasFileAccess (typeId t
)
2108 return (typeIdSet_member (gc
.facct
, t
));
2111 static /*@only@*/ cstring
2112 context_unparseAccess (void)
2114 return (message ("%q / %q", typeIdSet_unparse (gc
.acct
),
2115 typeIdSet_unparse (gc
.facct
)));
2119 context_unparseClauses (void)
2121 return (clauseStack_unparse (gc
.clauses
));
2125 context_couldHaveAccess (typeId t
)
2127 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
|| gc
.kind
== CX_UNKNOWNMACRO
)
2129 return (typeIdSet_member (gc
.acct
, t
));
2133 return (typeIdSet_member (gc
.facct
, t
));
2138 context_getRetType (void)
2140 ctype f
= ctype_undefined
;
2142 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
)
2144 f
= uentry_getType (gc
.cont
.fcn
);
2146 else if (gc
.kind
== CX_UNKNOWNMACRO
)
2148 return ctype_unknown
;
2152 llcontbuglit ("context_getRetType: not in a function context");
2153 return ctype_unknown
;
2156 if (!ctype_isFunction (f
))
2158 if (ctype_isKnown (f
))
2160 llbuglit ("context_getRetType: not a function");
2163 return ctype_unknown
;
2165 return (ctype_getReturnType (f
));
2169 context_hasMods (void)
2171 if (context_inFunctionLike ())
2173 return (uentry_hasMods (gc
.cont
.fcn
));
2182 context_exitAllClauses (void)
2184 while (!clauseStack_isEmpty (gc
.clauses
))
2186 clause el
= clauseStack_top (gc
.clauses
);
2189 if (clause_isNone (el
))
2191 usymtab_quietExitScope (g_currentloc
);
2195 context_setJustPopped ();
2196 if (el
== FALSECLAUSE
)
2198 usymtab_popBranches (exprNode_undefined
, exprNode_undefined
, exprNode_undefined
, FALSE
, el
);
2202 usymtab_popTrueBranch (exprNode_undefined
, exprNode_undefined
, el
);
2204 llassert (clauseStack_top (gc
.clauses
) == el
);
2207 clauseStack_pop (gc
.clauses
);
2210 clauseStack_clear (gc
.clauses
);
2211 gc
.inclause
= NOCLAUSE
;
2215 context_exitAllClausesQuiet (void)
2217 while (!clauseStack_isEmpty (gc
.clauses
))
2219 clause el
= clauseStack_top (gc
.clauses
);
2222 usymtab_quietExitScope (g_currentloc
);
2223 clauseStack_pop (gc
.clauses
);
2226 clauseStack_clear (gc
.clauses
);
2227 gc
.inclause
= NOCLAUSE
;
2231 void context_exitClauseSimp (void)
2233 context_setJustPopped ();
2234 clauseStack_pop (gc
.clauses
);
2235 gc
.inclause
= topClause (gc
.clauses
);
2239 ** Expected to be used when a switch/case is imbricated with another block, e.g.
2240 ** a loop (while, do-while, for) as in Duff's device, but also the true/false
2241 ** branch of an if/else. Code like:
2256 ** is legal code in C, and this routine is used to handle such cases.
2259 void context_exitCaseClause (bool popsymtab
)
2263 context_setJustPopped ();
2264 usymtab_popCaseBranch ();
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 void context_exitWhileClause (exprNode pred
, exprNode body
)
2291 guardSet invGuards
= guardSet_invert (exprNode_getGuards (pred
));
2293 if (gc
.inclause
== CASECLAUSE
)
2294 context_exitCaseClause (TRUE
);
2295 if (gc
.inclause
!= WHILECLAUSE
)
2297 llparseerror (cstring_makeLiteral
2298 ("Likely parse error. While clause is inconsistent."));
2302 context_setJustPopped ();
2305 ** predicate must be false after while loop (unless there are breaks)
2308 if (context_getFlag (FLG_WHILELOOPEXEC
))
2310 usymtab_popTrueExecBranch (pred
, body
, WHILECLAUSE
);
2314 usymtab_popTrueBranch (pred
, body
, WHILECLAUSE
);
2317 usymtab_addGuards (invGuards
);
2318 guardSet_free (invGuards
);
2320 clauseStack_pop (gc
.clauses
);
2321 gc
.inclause
= topClause (gc
.clauses
);
2324 void context_exitDoWhileClause (exprNode pred
)
2326 guardSet invGuards
= guardSet_invert (exprNode_getGuards (pred
));
2328 /* should investigate why doesn't do-while like popping symtab */
2329 if (gc
.inclause
== CASECLAUSE
)
2330 context_exitCaseClause (FALSE
);
2331 if (gc
.inclause
!= DOWHILECLAUSE
)
2333 llparseerror (cstring_makeLiteral
2334 ("Likely parse error. Do-while clause is inconsistent."));
2338 context_setJustPopped ();
2340 usymtab_addGuards (invGuards
);
2341 guardSet_free (invGuards
);
2343 clauseStack_pop (gc
.clauses
);
2344 gc
.inclause
= topClause (gc
.clauses
);
2347 void context_exitForClause (exprNode forPred
, exprNode body
)
2349 guardSet invGuards
= guardSet_invert (exprNode_getForGuards (forPred
));
2351 if (gc
.inclause
== CASECLAUSE
)
2352 context_exitCaseClause (TRUE
);
2353 if (gc
.inclause
!= FORCLAUSE
)
2355 llparseerror (cstring_makeLiteral
2356 ("Likely parse error. For clause is inconsistent."));
2360 context_setJustPopped ();
2362 DPRINTF (("Exit for: %s / %s", exprNode_unparse (forPred
), exprNode_unparse (body
)));
2365 ** Predicate must be false after for loop (unless there are breaks)
2368 if (context_getFlag (FLG_FORLOOPEXEC
))
2370 DPRINTF (("Here: for loop exec"));
2371 usymtab_popTrueExecBranch (forPred
, body
, FORCLAUSE
);
2375 if (context_getFlag (FLG_OBVIOUSLOOPEXEC
)
2376 && exprNode_loopMustExec (forPred
))
2378 DPRINTF (("Here: loop must exec"));
2379 usymtab_popTrueExecBranch (forPred
, body
, FORCLAUSE
);
2383 DPRINTF (("Pop true branch:"));
2384 usymtab_popTrueBranch (forPred
, body
, FORCLAUSE
);
2388 usymtab_addGuards (invGuards
);
2389 guardSet_free (invGuards
);
2390 clauseStack_pop (gc
.clauses
);
2391 gc
.inclause
= topClause (gc
.clauses
);
2394 void context_exitConditionalClause (exprNode pred
, exprNode tbranch
, exprNode fbranch
)
2396 if (gc
.inclause
== CASECLAUSE
)
2397 context_exitCaseClause (TRUE
);
2398 if (!(gc
.inclause
== TRUECLAUSE
|| gc
.inclause
== FALSECLAUSE
))
2400 llparseerror (cstring_makeLiteral
2401 ("Likely parse error. Conditional clauses are inconsistent."));
2405 context_setJustPopped ();
2406 if (gc
.inclause
== FALSECLAUSE
)
2408 usymtab_popBranches (pred
, tbranch
, fbranch
, FALSE
, gc
.inclause
);
2412 usymtab_popTrueBranch (pred
, tbranch
, gc
.inclause
);
2414 llassert (clauseStack_top (gc
.clauses
) == gc
.inclause
);
2415 clauseStack_pop (gc
.clauses
);
2416 gc
.inclause
= topClause (gc
.clauses
);
2420 context_returnFunction (void)
2422 usymtab_checkFinalScope (TRUE
);
2426 context_exitFunction (void)
2428 DPRINTF (("Exit function: %s", context_unparse ()));
2430 if (!context_inFunction () && !context_inMacroConstant ()
2431 && !context_inUnknownMacro ()
2432 && !context_inIterDef () && !context_inIterEnd ())
2435 ** not a bug because of parse errors
2442 if (context_inMacro () && usymtab_inFunctionScope ())
2444 usymtab_exitScope (exprNode_undefined
);
2447 if (uentry_hasGlobs (gc
.cont
.fcn
))
2449 exprChecks_checkUsedGlobs (gc
.globs
, gc
.globs_used
);
2453 if (uentry_hasMods (gc
.cont
.fcn
))
2455 if (context_getFlag (FLG_MUSTMOD
))
2457 exprNode_checkAllMods (gc
.mods
, gc
.cont
.fcn
);
2461 DPRINTF (("Exit function: %s", uentry_unparse (gc
.cont
.fcn
)));
2464 ** clear file static modifies
2467 /* do this first to get unused error messages */
2469 usymtab_exitScope (exprNode_undefined
);
2470 sRef_exitFunctionScope ();
2472 gc
.showfunction
= FALSE
;
2473 gc
.kind
= CX_GLOBAL
;
2474 gc
.cont
.glob
= TRUE
;
2476 gc
.globs
= globSet_new ();
2477 globSet_clear (gc
.globs_used
);
2478 gc
.mods
= sRefSet_new ();
2481 llassert (clauseStack_isEmpty (gc
.clauses
));
2482 llassert (gc
.inclause
== NOCLAUSE
);
2483 DPRINTF (("After exit function: %s", context_unparse ()));
2487 context_quietExitFunction (void)
2489 while (gc
.kind
== CX_INNER
)
2491 context_exitInnerPlain ();
2494 if (!context_inFunction () && !context_inMacroConstant () && !context_inUnknownMacro ()
2495 && !context_inIterDef () && !context_inIterEnd ())
2500 usymtab_quietExitScope (g_currentloc
);
2502 gc
.showfunction
= FALSE
;
2503 gc
.kind
= CX_GLOBAL
;
2504 gc
.cont
.glob
= TRUE
;
2506 gc
.globs
= globSet_new ();
2507 globSet_clear (gc
.globs_used
);
2508 gc
.mods
= sRefSet_new ();
2510 sRef_exitFunctionScope ();
2514 /*@observer@*/ uentryList
2515 context_getParams (void)
2517 if (context_inFunctionLike ())
2519 return (uentry_getParams (gc
.cont
.fcn
));
2523 llcontbug (message ("context_getParams: not in function: %q", context_unparse ()));
2524 return uentryList_undefined
;
2528 /*@observer@*/ globSet
2529 context_getUsedGlobs (void)
2531 llassert (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
2532 || gc
.kind
== CX_UNKNOWNMACRO
|| gc
.kind
== CX_ITERDEF
);
2534 return (gc
.globs_used
);
2538 context_moduleName (void)
2540 return (fileloc_getBase (g_currentloc
));
2543 /*@observer@*/ globSet
2544 context_getGlobs (void)
2546 llassert (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
2547 || gc
.kind
== CX_UNKNOWNMACRO
|| gc
.kind
== CX_ITERDEF
);
2553 context_addBoolAccess (void)
2555 cstring bname
= context_getString (FLG_BOOLTYPE
);
2556 typeIdSet boolt
= typeIdSet_single (usymtab_getTypeId (bname
));
2558 addModuleAccess (cstring_copy (bname
), boolt
);
2560 /* for sys/types (perhaps, this is bogus!) */
2561 addModuleAccess (cstring_makeLiteral ("types"), boolt
);
2566 context_canAccessBool (void)
2573 static typeId boolType = typeId_invalid;
2575 if (typeId_isInvalid (boolType))
2577 boolType = usymtab_getTypeId (context_getBoolName ());
2580 if (typeId_isInvalid (boolType)) {
2583 return (typeIdSet_member (gc.acct, boolType));
2588 /* evs 2000-07-25: old version - replaced */
2591 context_boolImplementationType (void) {
2592 /* For now, this is bogus! */
2597 context_canAccessBool (void)
2599 static typeId boolType
= typeId_invalid
;
2601 if (typeId_isInvalid (boolType
))
2603 boolType
= usymtab_getTypeId (context_getBoolName ());
2606 if (!typeId_isInvalid (boolType
))
2608 return context_hasAccess (boolType
);
2619 context_setMessageAnnote (/*@only@*/ cstring s
)
2621 llassert (cstring_isUndefined (gc
.msgAnnote
));
2626 context_hasMessageAnnote (void)
2628 return (cstring_isDefined (gc
.msgAnnote
));
2632 context_clearMessageAnnote (void)
2634 if (cstring_isDefined (gc
.msgAnnote
))
2636 cstring_free (gc
.msgAnnote
);
2637 gc
.msgAnnote
= cstring_undefined
;
2642 context_getMessageAnnote (void)
2644 cstring st
= gc
.msgAnnote
;
2646 gc
.msgAnnote
= cstring_undefined
;
2651 context_setAliasAnnote (/*@observer@*/ sRef s
, /*@observer@*/ sRef t
)
2653 llassert (sRef_isInvalid (gc
.aliasAnnote
));
2654 llassert (!sRef_sameName (s
, t
));
2656 gc
.aliasAnnoteAls
= t
;
2660 context_hasAliasAnnote (void)
2662 return (sRef_isValid (gc
.aliasAnnote
));
2666 context_clearAliasAnnote (void)
2668 gc
.aliasAnnote
= sRef_undefined
;
2672 context_getAliasAnnote (void)
2674 sRef ret
= gc
.aliasAnnote
;
2675 sRef als
= gc
.aliasAnnoteAls
;
2677 llassert (sRef_isValid (ret
) && sRef_isValid (als
));
2679 gc
.aliasAnnote
= sRef_undefined
;
2680 return (message ("%q aliases %q", sRef_unparse (als
), sRef_unparse (ret
)));
2684 context_recordFileModifies (sRefSet mods
)
2686 gc
.modrecs
= sRefSetList_add (gc
.modrecs
, mods
);
2690 context_recordFileGlobals (globSet mods
)
2692 DPRINTF (("Recording file globals: %s", globSet_unparse (mods
)));
2693 /*@access globSet@*/ context_recordFileModifies (mods
); /*@noaccess globSet@*/
2697 context_setCommentMarkerChar (char c
)
2699 llassert (c
!= '\0');
2701 context_setValue (FLG_COMMENTCHAR
, (int) c
);
2705 context_getCommentMarkerChar (void)
2707 return ((char) context_getValue (FLG_COMMENTCHAR
));
2711 context_setValue (flagcode flag
, int val
)
2713 int index
= flagcode_valueIndex (flag
);
2715 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2723 llerror_flagWarning (message ("Value for %s must be a positive "
2724 "number (given %d)",
2725 flagcode_unparse (flag
), val
));
2728 if (flag
== FLG_LINELEN
&& val
< MINLINELEN
)
2730 llerror_flagWarning (message ("Value for %s must be at least %d (given %d)",
2731 flagcode_unparse (flag
),
2737 case FLG_INCLUDENEST
:
2738 case FLG_CONTROLNESTDEPTH
:
2739 case FLG_STRINGLITERALLEN
:
2740 case FLG_NUMSTRUCTFIELDS
:
2741 case FLG_NUMENUMMEMBERS
:
2742 case FLG_INDENTSPACES
:
2745 llerror_flagWarning (message ("Value for %s must be a non-negative "
2746 "number (given %d)",
2747 flagcode_unparse (flag
), val
));
2756 DPRINTF (("Set value [%s] %d = %d", flagcode_unparse (flag
), index
, val
));
2757 gc
.values
[index
] = val
;
2761 context_setValueAndFlag (flagcode flag
, int val
)
2763 gc
.flags
[flag
] = TRUE
;
2764 context_setValue (flag
, val
);
2768 context_getValue (flagcode flag
)
2770 int index
= flagcode_valueIndex (flag
);
2772 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2773 DPRINTF (("Get value [%s] %d = %d", flagcode_unparse (flag
), index
, gc
.values
[index
]));
2774 return (gc
.values
[index
]);
2779 context_getCounter (flagcode flag
)
2781 int index
= flagcode_valueIndex (flag
);
2783 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2784 return (gc
.counters
[index
]);
2788 context_incCounter (flagcode flag
)
2790 int index
= flagcode_valueIndex (flag
);
2792 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2794 gc
.counters
[index
]++;
2798 context_decCounter (flagcode flag
)
2800 int index
= flagcode_valueIndex (flag
);
2802 llassert (index
>= 0 && index
<= NUMVALUEFLAGS
);
2803 gc
.counters
[index
]--;
2805 # endif /* DEADCODE */
2807 bool context_showFunction (void)
2809 return (gc
.showfunction
);
2813 context_setString (flagcode flag
, cstring val
)
2815 int index
= flagcode_stringIndex (flag
);
2817 llassert (index
>= 0 && index
<= NUMSTRINGFLAGS
);
2819 DPRINTF (("set string: %s", flagcode_unparse (flag
)));
2823 case FLG_MESSAGESTREAM
:
2824 case FLG_WARNINGSTREAM
:
2825 case FLG_ERRORSTREAM
:
2827 if (cstring_isDefined (val
))
2831 if (osd_fileExists (val
))
2833 if (context_getFlag (FLG_STREAMOVERWRITE
))
2835 llfatalerror (message
2836 ("Output stream file %s would overwrite existing file. "
2837 "Use -streamoverwrite if you want to allow this.",
2842 fstream
= fopen (cstring_toCharsSafe (val
), "w");
2844 if (fstream
== NULL
)
2846 llfatalerror (message ("Unable to open output stream file %s for writing",
2851 ** This ensures fstream will be closed on exit.
2854 fileTable_addStreamFile (gc
.ftab
, fstream
, cstring_copy (val
));
2858 case FLG_MESSAGESTREAM
:
2859 g_messagestream
= fstream
;
2860 /*@innerbreak@*/ break;
2861 case FLG_WARNINGSTREAM
:
2862 g_warningstream
= fstream
;
2863 /*@innerbreak@*/ break;
2864 case FLG_ERRORSTREAM
:
2865 g_errorstream
= fstream
;
2866 /*@innerbreak@*/ break;
2869 /*@-statetransfer@*/
2870 } /*@=statetransfer@*/ /* fstream not closed, but will be on exit */
2873 case FLG_SYSTEMDIRS
:
2875 llassert (cstring_isDefined (val
));
2877 if (cstring_firstChar (val
) == '\"')
2880 cstring tval
= cstring_copy (cstring_suffix (val
, 1));
2882 if (cstring_lastChar (tval
) != '\"')
2884 int n
= size_toInt (cstring_length (tval
) - 1);
2886 while (isspace ((int) cstring_getChar (tval
, size_fromInt (n
))))
2891 if (cstring_getChar (tval
, size_fromInt (n
)) != '\"')
2894 (message ("Setting -systemdirs to string with unmatching quotes: %s", val
));
2898 cstring otval
= tval
;
2899 tval
= cstring_prefix (tval
, size_fromInt (n
));
2900 cstring_free (otval
);
2904 val
= cstring_copy (cstring_clip (tval
, cstring_length (tval
) - 1));
2905 DPRINTF (("val = %s", val
));
2906 cstring_free (tval
);
2907 cstring_free (oval
);
2914 llassert (cstring_isDefined (val
));
2916 if (cstring_length (val
) == 0)
2919 val
= message (".%s", cstring_makeLiteralTemp (CONNECTSTR
));
2921 else if (cstring_lastChar (val
) != CONNECTCHAR
)
2923 val
= cstring_appendChar (val
, CONNECTCHAR
);
2933 ; /* Okay not handle everything in this switch */
2936 } /* evans 2002-03-24: splintme reports a spurious (I think) warning here...need to look into it */
2939 if (cstring_length (val
) >= 1
2940 && cstring_firstChar (val
) == '\"')
2942 llerror_flagWarning (message
2943 ("Setting %s to string beginning with \". You probably "
2944 "don't meant to have the \"'s.",
2945 flagcode_unparse (flag
)));
2948 gc
.strings
[index
] = val
;
2951 static /*@exposed@*/ cstring
2952 context_exposeString (flagcode flag
)
2954 int index
= flagcode_stringIndex (flag
);
2956 llassert (index
>= 0 && index
<= NUMSTRINGFLAGS
);
2957 return (gc
.strings
[index
]);
2961 context_getString (flagcode flag
)
2963 return (context_exposeString (flag
));
2967 context_resetErrors (void)
2973 context_recordBug (void)
2979 context_numBugs (void)
2984 void context_initMod (void)
2985 /*@globals undef gc; @*/
2987 gc
.kind
= CX_GLOBAL
;
2989 gc
.savekind
= CX_ERROR
;
2990 gc
.savecont
.glob
= FALSE
;
2992 gc
.instandardlib
= FALSE
;
2996 gc
.linesprocessed
= 0;
2997 gc
.speclinesprocessed
= 0;
2998 gc
.insuppressregion
= FALSE
;
2999 gc
.macroMissingParams
= FALSE
;
3000 gc
.preprocessing
= FALSE
;
3001 gc
.incommandline
= FALSE
;
3002 gc
.mc
= macrocache_create ();
3004 gc
.maxmods
= DEFAULTMAXMODS
;
3005 gc
.moduleaccess
= (maccesst
*) dmalloc (sizeof (*gc
.moduleaccess
) * (gc
.maxmods
));
3007 gc
.library
= FLG_STDLIB
;
3009 gc
.locstack
= filelocStack_new ();
3010 gc
.modrecs
= sRefSetList_undefined
;
3011 gc
.anyExports
= FALSE
;
3013 gc
.ftab
= fileTable_create ();
3014 gc
.msgLog
= messageLog_new ();
3015 gc
.inimport
= FALSE
;
3016 gc
.inDerivedFile
= FALSE
;
3017 gc
.inheader
= FALSE
;
3018 gc
.markers
= flagMarkerList_new ();
3019 gc
.cont
.glob
= TRUE
;
3020 gc
.showfunction
= FALSE
;
3021 gc
.msgAnnote
= cstring_undefined
;
3022 gc
.aliasAnnote
= sRef_undefined
;
3023 gc
.aliasAnnoteAls
= sRef_undefined
;
3024 gc
.boolType
= ctype_bool
;
3025 gc
.mods
= sRefSet_new ();
3027 gc
.saveloc
= fileloc_undefined
;
3029 gc
.inmacrocache
= FALSE
;
3030 gc
.inclause
= NOCLAUSE
;
3031 gc
.clauses
= clauseStack_new ();
3032 gc
.globs
= globSet_new ();
3033 gc
.nacct
= typeIdSet_emptySet ();
3034 gc
.acct
= typeIdSet_emptySet ();
3035 gc
.facct
= typeIdSet_emptySet ();
3036 gc
.savedFlags
= FALSE
;
3037 gc
.pushloc
= fileloc_undefined
;
3038 gc
.protectVars
= FALSE
;
3039 gc
.justpopped
= FALSE
;
3040 gc
.isNullGuarded
= NO
;
3041 gc
.globs_used
= globSet_undefined
;
3045 gc
.setGlobally
[code
] = FALSE
;
3046 gc
.setLocally
[code
] = FALSE
;
3051 context_resetAllFlags ();
3053 assertSet (gc
.flags
); /* Can't use global in defines */
3054 assertSet (gc
.saveflags
);
3055 assertSet (gc
.values
);
3056 assertSet (gc
.strings
);
3058 conext_resetAllCounters ();
3059 assertSet (gc
.counters
);
3061 context_setMode (DEFAULT_MODE
);
3063 gc
.stateTable
= metaStateTable_create ();
3064 gc
.annotTable
= annotationTable_create ();
3066 gc
.inFunctionHeader
= FALSE
;
3068 DPRINTF (("Annotations: \n%s",
3069 cstring_toCharsSafe (annotationTable_unparse (gc
.annotTable
))));
3070 DPRINTF (("State: \n%s",
3071 cstring_toCharsSafe (metaStateTable_unparse (gc
.stateTable
))));
3076 context_typeofZero (void)
3078 ctype ct
= ctype_int
;
3080 if (context_getFlag (FLG_ZEROPTR
))
3082 ct
= ctype_makeConj (ct
, ctype_voidPointer
);
3085 if (context_getFlag (FLG_ZEROBOOL
)) {
3086 ct
= ctype_makeConj (ct
, ctype_bool
);
3093 context_typeofOne (void)
3095 ctype ct
= ctype_int
;
3097 /* 1 is on longer a bool (was before 2.4)
3098 if (!context_getFlag (FLG_ABSTRACTBOOL))
3100 ct = ctype_makeConj (ct, ctype_bool);
3108 context_unparse (void)
3115 s
= message ("LCL File: %q", fileloc_unparse (g_currentloc
));
3118 s
= message ("LCL Lib File: %q", fileloc_unparse (g_currentloc
));
3121 s
= message ("Global Context:%q", fileloc_unparse (g_currentloc
));
3124 s
= message ("Inner Context [%d] : %q",
3126 fileloc_unparse (g_currentloc
));
3129 s
= message ("Function %q :%q \n\taccess %q\n\tmodifies %q",
3130 uentry_unparse (gc
.cont
.fcn
),
3131 fileloc_unparse (g_currentloc
),
3132 typeIdSet_unparse (gc
.acct
),
3133 sRefSet_unparse (gc
.mods
));
3136 s
= message ("Function Macro %q", uentry_unparse (gc
.cont
.fcn
));
3138 case CX_UNKNOWNMACRO
:
3139 s
= message ("Forward Specified Macro %q", uentry_unparse (gc
.cont
.fcn
));
3142 s
= message ("Constant Macro %q", uentry_unparse (gc
.cont
.fcn
));
3145 s
= message ("Iter definition %q", uentry_unparse (gc
.cont
.fcn
));
3148 s
= message ("Iter end %q", uentry_unparse (gc
.cont
.fcn
));
3150 case CX_FCNDECLARATION
:
3151 s
= message ("Function declaration %q", uentry_unparse (gc
.cont
.fcn
));
3154 s
= message ("Un-unparseable context: %d", (int) gc
.kind
);
3158 s
= message ("%q\naccess: %q", s
, context_unparseAccess ());
3163 context_currentFunctionType (void)
3165 if (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
)
3167 return (uentry_getType (gc
.cont
.fcn
));
3169 else if (gc
.kind
== CX_INNER
)
3171 llcontbuglit ("context_currentFunctionType: inner context");
3172 do { context_exitInnerPlain (); } while (gc
.kind
== CX_INNER
);
3173 return (context_currentFunctionType ());
3177 llcontbuglit ("context_currentFunctionType: not in function");
3178 return (ctype_undefined
);
3183 context_enterInnerContext (void)
3185 if (context_getFlag (FLG_GRAMMAR
))
3187 lldiagmsg (message ("Enter inner context: %q", context_unparse ()));
3190 if (gc
.kind
== CX_GLOBAL
)
3195 else if (gc
.kind
== CX_INNER
)
3204 usymtab_enterScope ();
3205 pushClause (NOCLAUSE
);
3209 context_exitInnerPlain (void) /*@modifies gc;@*/
3211 context_exitInner (exprNode_undefined
);
3215 context_exitInner (exprNode exp
)
3217 if (context_getFlag (FLG_GRAMMAR
))
3219 lldiagmsg (message ("Exit inner context: %q", context_unparse ()));
3222 llassertprint (gc
.inclause
== NOCLAUSE
|| gc
.inclause
== CASECLAUSE
,
3223 ("inclause = %s", clause_nameTaken (gc
.inclause
)));
3225 clauseStack_removeFirst (gc
.clauses
, NOCLAUSE
);
3226 gc
.inclause
= topClause (gc
.clauses
);
3228 if (gc
.kind
== CX_INNER
)
3230 if (--gc
.cont
.cdepth
== 0)
3232 gc
.kind
= CX_GLOBAL
;
3233 gc
.cont
.glob
= TRUE
;
3238 if (gc
.kind
== CX_GLOBAL
)
3240 llcontbuglit ("Attempt to exit global context");
3245 usymtab_exitScope (exp
);
3250 context_enterStructInnerContext (void)
3252 if (context_getFlag (FLG_GRAMMAR
))
3254 lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
3257 if (gc
.kind
== CX_GLOBAL
)
3262 else if (gc
.kind
== CX_INNER
)
3271 usymtab_enterScope ();
3273 if (context_getFlag (FLG_GRAMMAR
))
3275 lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
3280 context_exitStructInnerContext (void)
3282 if (context_getFlag (FLG_GRAMMAR
))
3284 lldiagmsg (message ("Exit struct inner context: %q [%d]", context_unparse (), gc
.cont
.cdepth
));
3287 if (gc
.kind
== CX_INNER
)
3289 if (gc
.cont
.cdepth
<= 0)
3291 llcontbuglit ("Attempt to exit inner context with no depth");
3292 gc
.kind
= CX_GLOBAL
;
3293 gc
.cont
.glob
= TRUE
;
3299 if (gc
.cont
.cdepth
== 0)
3301 gc
.kind
= CX_GLOBAL
;
3302 gc
.cont
.glob
= TRUE
;
3308 if (gc
.kind
== CX_GLOBAL
)
3310 llcontbuglit ("Attempt to exit global context");
3315 usymtab_exitScope (exprNode_undefined
);
3317 if (context_getFlag (FLG_GRAMMAR
))
3319 lldiagmsg (message ("After exit struct inner context: %q [%d]", context_unparse (), gc
.cont
.cdepth
));
3324 context_exitInnerSafe (void)
3326 if (context_getFlag (FLG_GRAMMAR
))
3328 lldiagmsg (message ("Exit inner safe: %q", context_unparse ()));
3331 if (gc
.kind
== CX_INNER
)
3333 if (--gc
.cont
.cdepth
<= 0)
3338 else if (gc
.kind
== CX_GLOBAL
)
3340 llcontbuglit ("Attempt to exit global context");
3345 if (usymtab_inDeepScope ())
3347 usymtab_exitScope (exprNode_undefined
);
3353 void setModuleAccess (void)
3355 gc
.facct
= typeIdSet_emptySet ();
3357 if (fileId_isValid (currentFile ()))
3359 cstring baseName
= fileloc_getBase (g_currentloc
);
3361 if (context_getFlag (FLG_ACCESSFILE
))
3363 if (usymtab_existsType (baseName
))
3365 gc
.facct
= typeIdSet_insert (gc
.facct
,
3366 usymtab_getTypeId (baseName
));
3374 if (context_getFlag (FLG_ACCESSMODULE
))
3378 for (i
= 0; i
< gc
.nmods
; i
++)
3380 if (cstring_equal (baseName
, gc
.moduleaccess
[i
].file
))
3382 gc
.facct
= typeIdSet_union (gc
.facct
, gc
.moduleaccess
[i
].daccess
);
3390 gc
.inheader
= fileId_isHeader (currentFile ());
3394 llcontbuglit ("Current file not defined\n");
3395 gc
.facct
= typeIdSet_emptySet ();
3397 gc
.inheader
= FALSE
;
3400 /* 17 Jan 1995: forgot to clear nacct */
3402 gc
.nacct
= typeIdSet_emptySet ();
3406 context_enterFileAux (void)
3412 context_enterFile (void)
3414 context_enterFileAux ();
3415 usymtab_enterFile ();
3419 context_enterMacroFile (void)
3421 context_enterFileAux ();
3425 context_inFunction (void)
3427 kcontext ck
= gc
.kind
;
3429 return ((ck
== CX_FUNCTION
) || (ck
== CX_MACROFCN
) || (ck
== CX_INNER
));
3433 context_inFunctionLike (void)
3435 return (gc
.kind
== CX_FUNCTION
|| gc
.kind
== CX_MACROFCN
3436 || gc
.kind
== CX_FCNDECLARATION
3437 || gc
.kind
== CX_UNKNOWNMACRO
|| gc
.kind
== CX_ITERDEF
);
3441 context_inRealFunction (void)
3443 kcontext ck
= gc
.kind
;
3445 return ((ck
== CX_FUNCTION
) || (ck
== CX_MACROFCN
));
3449 context_processAllMacros (void)
3451 usymtab_enterFile ();
3453 gc
.inmacrocache
= TRUE
;
3454 macrocache_processUndefinedElements (gc
.mc
);
3456 usymtab_exitFile ();
3458 gc
.inmacrocache
= FALSE
;
3459 macrocache_finalize ();
3463 ** this happens once at the end of each C file
3465 ** check each Macro that was defined in current file.c or current file.h
3470 context_processMacros (void)
3472 if (fileId_isValid (currentFile ()))
3475 cstring cbase
= fileLib_removePathFree (fileLib_removeAnyExtension (fileTable_fileName (currentFile ())));
3477 gc
.inmacrocache
= TRUE
;
3479 DPRINTF (("Processing macros: %s", cbase
));
3480 lastfl
= macrocache_processFileElements (gc
.mc
, cbase
);
3481 DPRINTF (("Processing macros: %s", fileloc_unparse (lastfl
)));
3483 cstring_free (cbase
);
3485 if (fileloc_isDefined (lastfl
))
3487 g_currentloc
= fileloc_update (g_currentloc
, lastfl
);
3491 gc
.inmacrocache
= FALSE
;
3496 context_processingMacros (void)
3498 return (gc
.inmacrocache
);
3502 context_exitCFile (void)
3504 if (gc
.kind
!= CX_GLOBAL
)
3507 (cstring_makeLiteral ("File ended outside global scope"));
3510 if (gc
.insuppressregion
)
3512 /* gack...don't reverse the order of these lines! ;-> */
3513 gc
.insuppressregion
= FALSE
;
3514 llerrorlit (FLG_SYNTAX
,
3515 "File ended in ignore errors region, "
3516 "possible missing /*@end*/");
3519 /* fix up parse errors */
3521 while (!usymtab_inFileScope ())
3523 usymtab_quietExitScope (g_currentloc
);
3527 ** Clear the file-specific modifies information.
3530 sRefSetList_elements (gc
.modrecs
, mods
)
3532 sRefSet_clearStatics (mods
);
3533 } end_sRefSetList_elements
;
3535 sRefSetList_clear (gc
.modrecs
);
3537 context_processMacros ();
3540 usymtab_exitFile ();
3542 gc
.inDerivedFile
= FALSE
;
3543 filelocStack_clear (gc
.locstack
);
3545 gc
.nacct
= typeIdSet_emptySet (); /* empty noaccess */
3547 gc
.cont
.glob
= TRUE
;
3551 context_restoreFlagSettings ();
3552 gc
.savedFlags
= FALSE
;
3556 DPRINTF (("After exiting file: "));
3557 usymtab_printAll ();
3562 context_exitMacroCache (void)
3564 if (gc
.kind
!= CX_GLOBAL
)
3566 if (context_inMacro ())
3567 /* this is okay, file could end without newline in macro */
3569 DPRINTF (("Still in macro: %s",
3570 context_unparse ()));
3571 context_exitFunction ();
3575 llcontbug (message ("context_exitMacroCache: outside global scope: %q",
3576 context_unparse ()));
3577 gc
.kind
= CX_GLOBAL
;
3582 ** no longer valid here
3583 ** if (gc.insuppressregion)
3585 ** gc.insuppressregion = FALSE;
3586 ** llerror ("File ended in ignore errors region, possible missing @");
3590 gc
.cont
.glob
= TRUE
;
3594 context_saveLocation (void)
3596 /* was llassert (fileloc_isUndefined (gc.saveloc)) */
3597 fileloc_free (gc
.saveloc
);
3598 gc
.saveloc
= fileloc_copy (g_currentloc
);
3602 context_getSaveLocation (void)
3604 fileloc fl
= gc
.saveloc
;
3605 gc
.saveloc
= fileloc_undefined
;
3609 /*@observer@*/ cstring
3610 context_inFunctionName (void)
3612 if (gc
.kind
== CX_FUNCTION
3613 || gc
.kind
== CX_MACROFCN
|| gc
.kind
== CX_UNKNOWNMACRO
3614 || gc
.kind
== CX_MACROCONST
3615 || gc
.kind
== CX_ITERDEF
|| gc
.kind
== CX_ITEREND
)
3617 return (uentry_rawName (gc
.cont
.fcn
));
3621 llcontbuglit ("context_inFunctionName: not in function");
3622 return (cstring_undefined
);
3627 context_userSetFlag (flagcode f
, bool b
)
3629 DPRINTF (("set flag: %s / %s",
3630 flagcode_unparse (f
),
3631 bool_unparse (context_getFlag (f
))));
3633 if (f
== FLG_NEVERINCLUDE
&& b
)
3635 if (gc
.flags
[FLG_EXPORTHEADER
])
3638 (cstring_makeLiteral
3639 ("Setting +neverinclude after +exportheader. "
3640 "Turning off exportheader, since headers are not checked "
3641 "when +neverinclude is used."));
3643 gc
.flags
[FLG_EXPORTHEADER
] = FALSE
;
3648 if (f
== FLG_EXPORTHEADER
&& b
)
3650 if (gc
.flags
[FLG_NEVERINCLUDE
])
3653 (cstring_makeLiteral
3654 ("Setting +exportheader after +neverinclude. "
3655 "Not setting exportheader, since headers are not checked "
3656 "when +neverinclude is used."));
3657 gc
.flags
[FLG_EXPORTHEADER
] = FALSE
;
3663 if (context_getFlag (FLG_WARNFLAGS
) && f
!= FLG_NOF
&& f
!= FLG_OPTF
)
3665 bool lastsetting
= context_getFlag (f
);
3667 if (bool_equal (lastsetting
, b
)
3668 && !flagcode_isSpecialFlag (f
)
3669 && !flagcode_isIdemFlag (f
)
3670 && !flagcode_hasArgument (f
))
3673 (message ("Setting %s%s redundant with current value",
3674 cstring_makeLiteralTemp (b
? "+" : "-"),
3675 flagcode_unparse (f
)));
3679 if (flagcode_isWarnUseFlag (f
) && b
)
3681 if (!context_getFlag (FLG_WARNUSE
))
3684 (message ("Flag +%s is canceled by -warnuse",
3685 flagcode_unparse (f
)));
3690 if (flagcode_isLibraryFlag (f
))
3692 static bool libSet
= FALSE
;
3700 (message ("Selecting library %s after library %s was "
3701 "selected (only one library may be used)",
3702 flagcode_unparse (f
),
3703 flagcode_unparse (gc
.library
)));
3706 if (f
== FLG_UNIXLIB
)
3708 if (context_getFlag (FLG_WARNUNIXLIB
))
3711 (cstring_makeLiteral
3712 ("Selecting unix library. Unix library is "
3713 "based on the Single Unix Specification, Version 2. Not all "
3714 "Unix implementations are consistent with this specification. "
3715 "Use -warnunixlib to suppress this message."));
3719 context_setLibrary (f
);
3722 if (flagcode_isNameChecksFlag (f
) && b
&& !context_maybeSet (FLG_NAMECHECKS
))
3726 ("Setting +%s will not produce warnings with -namechecks. "
3727 "Must set +namechecks also.",
3728 flagcode_unparse (f
)));
3731 gc
.setGlobally
[f
] = TRUE
;
3732 context_setFlag (f
, b
, g_currentloc
);
3736 context_fileSetFlag (flagcode f
, ynm set
, fileloc loc
)
3740 context_saveFlagSettings ();
3743 if (ynm_isOff (set
))
3745 context_setFlagAux (f
, FALSE
, TRUE
, FALSE
, loc
);
3747 else if (ynm_isOn (set
))
3749 context_setFlagAux (f
, TRUE
, TRUE
, FALSE
, loc
);
3750 gc
.setLocally
[f
] = TRUE
;
3754 context_restoreFlag (f
, loc
);
3759 context_restoreFlag (flagcode f
, fileloc loc
)
3765 message ("Attempt to restore flag %s when no file scope flags "
3767 flagcode_unparse (f
)),
3772 context_addFlagMarker (f
, MAYBE
, loc
);
3773 context_setFlagAux (f
, gc
.saveflags
[f
], FALSE
, TRUE
, loc
);
3779 context_setFlag (flagcode f
, bool b
, fileloc loc
)
3781 context_setFlagAux (f
, b
, FALSE
, FALSE
, loc
);
3785 context_setFlagTemp (flagcode f
, bool b
)
3787 DPRINTF (("Set flag temp: %s / %s", flagcode_unparse (f
), bool_unparse (b
)));
3792 # define DOSET(ff,b) \
3793 do { if (inFile) { gc.setLocally[ff] = TRUE; \
3794 context_addFlagMarker (ff, ynm_fromBool (b), loc); } \
3795 DPRINTF (("set flag: %s / %s", flagcode_unparse (ff), bool_unparse (b))); \
3796 gc.flags[ff] = b; } while (FALSE)
3799 context_setFlagAux (flagcode f
, bool b
, bool inFile
,
3800 /*@unused@*/ bool isRestore
, fileloc loc
)
3802 DPRINTF (("Set flag: %s / %s", flagcode_unparse (f
), bool_unparse (b
)));
3805 ** Removed test for special flags.
3808 if (flagcode_isIdemFlag (f
))
3817 if (f
>= FLG_ITS4MOSTRISKY
&& f
<= FLG_ITS4LOWRISK
)
3819 if (b
) /* Turing higher level on, turns on all lower levels */
3823 case FLG_ITS4MOSTRISKY
:
3824 DOSET (FLG_ITS4VERYRISKY
, b
);
3826 case FLG_ITS4VERYRISKY
:
3827 DOSET (FLG_ITS4RISKY
, b
);
3830 DOSET (FLG_ITS4MODERATERISK
, b
);
3832 case FLG_ITS4MODERATERISK
:
3833 DOSET (FLG_ITS4LOWRISK
, b
);
3835 case FLG_ITS4LOWRISK
:
3840 else /* Turning level off, turns off all higher levels */
3844 case FLG_ITS4LOWRISK
:
3845 DOSET (FLG_ITS4MODERATERISK
, b
);
3847 case FLG_ITS4MODERATERISK
:
3848 DOSET (FLG_ITS4RISKY
, b
);
3851 DOSET (FLG_ITS4VERYRISKY
, b
);
3853 case FLG_ITS4VERYRISKY
:
3854 DOSET (FLG_ITS4MOSTRISKY
, b
);
3856 case FLG_ITS4MOSTRISKY
:
3865 case FLG_MESSAGESTREAMSTDOUT
:
3866 g_messagestream
= stdout
;
3868 case FLG_MESSAGESTREAMSTDERR
:
3869 g_messagestream
= stderr
;
3871 case FLG_WARNINGSTREAMSTDOUT
:
3872 g_warningstream
= stdout
;
3874 case FLG_WARNINGSTREAMSTDERR
:
3875 g_warningstream
= stderr
;
3877 case FLG_ERRORSTREAMSTDOUT
:
3878 g_errorstream
= stdout
;
3880 case FLG_ERRORSTREAMSTDERR
:
3881 g_errorstream
= stderr
;
3884 DOSET (FLG_ALLEMPTY
, b
);
3885 DOSET (FLG_IFEMPTY
, b
);
3886 DOSET (FLG_WHILEEMPTY
, b
);
3887 DOSET (FLG_FOREMPTY
, b
);
3890 DOSET (FLG_PREDBOOL
, b
);
3891 DOSET (FLG_PREDBOOLINT
, b
);
3892 DOSET (FLG_PREDBOOLPTR
, b
);
3893 DOSET (FLG_PREDBOOLOTHERS
, b
);
3896 DOSET (FLG_CHECKSTRICTGLOBALIAS
, b
);
3897 DOSET (FLG_CHECKEDGLOBALIAS
, b
);
3898 DOSET (FLG_CHECKMODGLOBALIAS
, b
);
3899 DOSET (FLG_UNCHECKEDGLOBALIAS
, b
);
3902 DOSET (FLG_ALLBLOCK
, b
);
3903 DOSET (FLG_IFBLOCK
, b
);
3904 DOSET (FLG_WHILEBLOCK
, b
);
3905 DOSET (FLG_FORBLOCK
, b
);
3919 DOSET (FLG_GRAMMAR
, b
);
3921 case FLG_CODEIMPONLY
:
3922 DOSET (FLG_CODEIMPONLY
, b
);
3923 DOSET (FLG_GLOBIMPONLY
, b
);
3924 DOSET (FLG_RETIMPONLY
, b
);
3925 DOSET (FLG_STRUCTIMPONLY
, b
);
3927 case FLG_SPECALLIMPONLY
:
3928 DOSET (FLG_SPECALLIMPONLY
, b
);
3929 DOSET (FLG_SPECGLOBIMPONLY
, b
);
3930 DOSET (FLG_SPECRETIMPONLY
, b
);
3931 DOSET (FLG_SPECSTRUCTIMPONLY
, b
);
3933 case FLG_ALLIMPONLY
:
3934 DOSET (FLG_ALLIMPONLY
, b
);
3935 DOSET (FLG_GLOBIMPONLY
, b
);
3936 DOSET (FLG_RETIMPONLY
, b
);
3937 DOSET (FLG_STRUCTIMPONLY
, b
);
3938 DOSET (FLG_SPECGLOBIMPONLY
, b
);
3939 DOSET (FLG_SPECRETIMPONLY
, b
);
3940 DOSET (FLG_SPECSTRUCTIMPONLY
, b
);
3942 case FLG_ANSI89LIMITS
:
3943 DOSET (FLG_ANSI89LIMITS
, b
);
3944 DOSET (FLG_CONTROLNESTDEPTH
, b
);
3945 DOSET (FLG_STRINGLITERALLEN
, b
);
3946 DOSET (FLG_INCLUDENEST
, b
);
3947 DOSET (FLG_NUMSTRUCTFIELDS
, b
);
3948 DOSET (FLG_NUMENUMMEMBERS
, b
);
3952 context_setValue (FLG_CONTROLNESTDEPTH
, ANSI89_CONTROLNESTDEPTH
);
3953 context_setValue (FLG_STRINGLITERALLEN
, ANSI89_STRINGLITERALLEN
);
3954 context_setValue (FLG_INCLUDENEST
, ANSI89_INCLUDENEST
);
3955 context_setValue (FLG_NUMSTRUCTFIELDS
, ANSI89_NUMSTRUCTFIELDS
);
3956 context_setValue (FLG_NUMENUMMEMBERS
, ANSI89_NUMENUMMEMBERS
);
3957 context_setValue (FLG_EXTERNALNAMELEN
, ANSI89_EXTERNALNAMELEN
);
3958 context_setValue (FLG_INTERNALNAMELEN
, ANSI89_INTERNALNAMELEN
);
3961 case FLG_ISO99LIMITS
:
3962 DOSET (FLG_ISO99LIMITS
, b
);
3963 DOSET (FLG_CONTROLNESTDEPTH
, b
);
3964 DOSET (FLG_STRINGLITERALLEN
, b
);
3965 DOSET (FLG_INCLUDENEST
, b
);
3966 DOSET (FLG_NUMSTRUCTFIELDS
, b
);
3967 DOSET (FLG_NUMENUMMEMBERS
, b
);
3971 context_setValue (FLG_CONTROLNESTDEPTH
, ISO99_CONTROLNESTDEPTH
);
3972 context_setValue (FLG_STRINGLITERALLEN
, ISO99_STRINGLITERALLEN
);
3973 context_setValue (FLG_INCLUDENEST
, ISO99_INCLUDENEST
);
3974 context_setValue (FLG_NUMSTRUCTFIELDS
, ISO99_NUMSTRUCTFIELDS
);
3975 context_setValue (FLG_NUMENUMMEMBERS
, ISO99_NUMENUMMEMBERS
);
3976 context_setValue (FLG_EXTERNALNAMELEN
, ISO99_EXTERNALNAMELEN
);
3977 context_setValue (FLG_INTERNALNAMELEN
, ISO99_INTERNALNAMELEN
);
3980 case FLG_EXTERNALNAMELEN
:
3981 DOSET (FLG_DISTINCTEXTERNALNAMES
, TRUE
);
3982 DOSET (FLG_EXTERNALNAMELEN
, TRUE
);
3984 case FLG_INTERNALNAMELEN
:
3985 DOSET (FLG_DISTINCTINTERNALNAMES
, TRUE
);
3986 DOSET (FLG_INTERNALNAMELEN
, TRUE
);
3988 case FLG_EXTERNALNAMECASEINSENSITIVE
:
3989 DOSET (FLG_EXTERNALNAMECASEINSENSITIVE
, b
);
3991 if (b
&& !gc
.flags
[FLG_DISTINCTEXTERNALNAMES
])
3993 DOSET (FLG_DISTINCTEXTERNALNAMES
, TRUE
);
3994 context_setValue (FLG_EXTERNALNAMELEN
, 0);
3997 case FLG_INTERNALNAMECASEINSENSITIVE
:
3998 DOSET (FLG_INTERNALNAMECASEINSENSITIVE
, b
);
4000 if (b
&& !gc
.flags
[FLG_DISTINCTINTERNALNAMES
])
4002 DOSET (FLG_DISTINCTINTERNALNAMES
, TRUE
);
4003 context_setValue (FLG_INTERNALNAMELEN
, 0);
4006 case FLG_INTERNALNAMELOOKALIKE
:
4007 DOSET (FLG_INTERNALNAMELOOKALIKE
, b
);
4009 if (b
&& !gc
.flags
[FLG_DISTINCTINTERNALNAMES
])
4011 DOSET (FLG_DISTINCTINTERNALNAMES
, TRUE
);
4012 context_setValue (FLG_INTERNALNAMELEN
, 0);
4016 DOSET (FLG_MODNOMODS
, b
);
4017 DOSET (FLG_MODGLOBSUNSPEC
, b
);
4018 DOSET (FLG_MODSTRICTGLOBSUNSPEC
, b
);
4021 DOSET (FLG_EXPORTVAR
, b
);
4022 DOSET (FLG_EXPORTFCN
, b
);
4023 DOSET (FLG_EXPORTTYPE
, b
);
4024 DOSET (FLG_EXPORTMACRO
, b
);
4025 DOSET (FLG_EXPORTCONST
, b
);
4026 gc
.anyExports
= TRUE
;
4029 DOSET (FLG_RETEXPOSE
, b
);
4030 DOSET (FLG_ASSIGNEXPOSE
, b
);
4031 DOSET (FLG_CASTEXPOSE
, b
);
4034 DOSET (FLG_RETVALBOOL
, b
);
4035 DOSET (FLG_RETVALINT
, b
);
4036 DOSET (FLG_RETVALOTHER
, b
);
4041 DOSET (FLG_EXPORTLOCAL
, FALSE
);
4042 DOSET (FLG_DECLUNDEF
, FALSE
);
4043 DOSET (FLG_SPECUNDEF
, FALSE
);
4044 DOSET (FLG_TOPUNUSED
, FALSE
);
4048 DOSET (FLG_LOOPLOOPBREAK
, b
);
4049 DOSET (FLG_LOOPSWITCHBREAK
, b
);
4050 DOSET (FLG_SWITCHLOOPBREAK
, b
);
4051 DOSET (FLG_SWITCHSWITCHBREAK
, b
);
4052 DOSET (FLG_LOOPLOOPCONTINUE
, b
);
4053 DOSET (FLG_DEEPBREAK
, b
);
4056 DOSET (FLG_FORLOOPEXEC
, b
);
4057 DOSET (FLG_WHILELOOPEXEC
, b
);
4058 DOSET (FLG_ITERLOOPEXEC
, b
);
4061 DOSET (FLG_ACCESSMODULE
, b
);
4062 DOSET (FLG_ACCESSFILE
, b
);
4063 DOSET (FLG_ACCESSCZECH
, b
);
4066 DOSET (FLG_ALLMACROS
, b
);
4067 DOSET (FLG_FCNMACROS
, b
);
4068 DOSET (FLG_CONSTMACROS
, b
);
4071 DOSET (FLG_BOUNDSREAD
, b
);
4072 DOSET (FLG_BOUNDSWRITE
, b
);
4073 DOSET (FLG_LIKELYBOUNDSREAD
, b
);
4074 DOSET (FLG_LIKELYBOUNDSWRITE
, b
);
4076 case FLG_BOUNDSREAD
:
4077 DOSET (FLG_LIKELYBOUNDSREAD
, b
);
4079 case FLG_BOUNDSWRITE
:
4080 DOSET (FLG_LIKELYBOUNDSWRITE
, b
);
4082 case FLG_LIKELYBOUNDS
:
4083 DOSET (FLG_LIKELYBOUNDSREAD
, b
);
4084 DOSET (FLG_LIKELYBOUNDSWRITE
, b
);
4088 if (b
) { DOSET (FLG_ACCESSCZECH
, b
); }
4089 DOSET (FLG_CZECHFUNCTIONS
, b
);
4090 DOSET (FLG_CZECHVARS
, b
);
4091 DOSET (FLG_CZECHCONSTANTS
, b
);
4092 DOSET (FLG_CZECHTYPES
, b
);
4095 if (b
) { DOSET (FLG_ACCESSSLOVAK
, b
); }
4096 DOSET (FLG_SLOVAKFUNCTIONS
, b
);
4097 DOSET (FLG_SLOVAKVARS
, b
);
4098 DOSET (FLG_SLOVAKCONSTANTS
, b
);
4099 DOSET (FLG_SLOVAKTYPES
, b
);
4101 case FLG_CZECHOSLOVAK
:
4102 if (b
) { DOSET (FLG_ACCESSCZECHOSLOVAK
, b
); }
4103 DOSET (FLG_CZECHOSLOVAKFUNCTIONS
, b
);
4104 DOSET (FLG_CZECHOSLOVAKVARS
, b
);
4105 DOSET (FLG_CZECHOSLOVAKCONSTANTS
, b
);
4106 DOSET (FLG_CZECHOSLOVAKTYPES
, b
);
4109 DOSET (FLG_NULLSTATE
, b
);
4110 DOSET (FLG_NULLDEREF
, b
);
4111 DOSET (FLG_NULLASSIGN
, b
);
4112 DOSET (FLG_NULLPASS
, b
);
4113 DOSET (FLG_NULLRET
, b
);
4116 DOSET (FLG_MUSTFREEONLY
, b
);
4117 DOSET (FLG_MUSTFREEFRESH
, b
);
4120 DOSET (FLG_NULLSTATE
, b
);
4121 DOSET (FLG_NULLDEREF
, b
);
4122 DOSET (FLG_NULLASSIGN
, b
);
4123 DOSET (FLG_NULLPASS
, b
);
4124 DOSET (FLG_NULLRET
, b
);
4125 DOSET (FLG_COMPDEF
, b
);
4126 DOSET (FLG_COMPMEMPASS
, b
);
4127 DOSET (FLG_UNIONDEF
, b
);
4128 DOSET (FLG_MEMTRANS
, b
);
4129 DOSET (FLG_USERELEASED
, b
);
4130 DOSET (FLG_ALIASUNIQUE
, b
);
4131 DOSET (FLG_MAYALIASUNIQUE
, b
);
4132 DOSET (FLG_MUSTFREEONLY
, b
);
4133 DOSET (FLG_MUSTFREEFRESH
, b
);
4134 DOSET (FLG_MUSTDEFINE
, b
);
4135 DOSET (FLG_GLOBSTATE
, b
);
4136 DOSET (FLG_COMPDESTROY
, b
);
4137 DOSET (FLG_MUSTNOTALIAS
, b
);
4138 DOSET (FLG_MEMIMPLICIT
, b
);
4139 DOSET (FLG_BRANCHSTATE
, b
);
4140 /*@fallthrough@*/ /* also sets memtrans flags */
4142 DOSET (FLG_MEMTRANS
, b
);
4143 DOSET (FLG_EXPOSETRANS
, b
);
4144 DOSET (FLG_OBSERVERTRANS
, b
);
4145 DOSET (FLG_DEPENDENTTRANS
, b
);
4146 DOSET (FLG_NEWREFTRANS
, b
);
4147 DOSET (FLG_ONLYTRANS
, b
);
4148 DOSET (FLG_OWNEDTRANS
, b
);
4149 DOSET (FLG_FRESHTRANS
, b
);
4150 DOSET (FLG_SHAREDTRANS
, b
);
4151 DOSET (FLG_TEMPTRANS
, b
);
4152 DOSET (FLG_KEPTTRANS
, b
);
4153 DOSET (FLG_REFCOUNTTRANS
, b
);
4154 DOSET (FLG_STATICTRANS
, b
);
4155 DOSET (FLG_UNKNOWNTRANS
, b
);
4156 DOSET (FLG_KEEPTRANS
, b
);
4157 DOSET (FLG_IMMEDIATETRANS
, b
);
4164 if (b
&& !gc
.anyExports
4165 && (f
== FLG_EXPORTVAR
|| f
== FLG_EXPORTFCN
4166 || f
== FLG_EXPORTTYPE
|| f
== FLG_EXPORTMACRO
4167 || f
== FLG_EXPORTCONST
4168 || f
== FLG_EXPORTANY
))
4170 gc
.anyExports
= TRUE
;
4175 context_maybeSet (flagcode d
)
4177 return (gc
.flags
[d
] || gc
.setLocally
[d
]);
4181 context_getFlag (flagcode d
)
4183 return (gc
.flags
[d
]);
4187 context_flagOn (flagcode f
, fileloc loc
)
4189 return (!context_suppressFlagMsg (f
, loc
));
4192 static void context_saveFlagSettings (void)
4194 gc
.savedFlags
= TRUE
;
4195 llassert (sizeof (gc
.saveflags
) == sizeof (gc
.flags
));
4196 memcpy (gc
.saveflags
, gc
.flags
, sizeof (gc
.flags
));
4199 static void context_restoreFlagSettings (void)
4201 llassert (sizeof (gc
.saveflags
) == sizeof (gc
.flags
));
4202 memcpy (gc
.flags
, gc
.saveflags
, sizeof (gc
.flags
));
4203 gc
.savedFlags
= FALSE
;
4206 void context_setFilename (fileId fid
, int lineno
)
4207 /*@globals fileloc g_currentloc;@*/
4208 /*@modifies g_currentloc@*/
4210 if (fileId_baseEqual (currentFile (), fid
))
4217 fileloc_setColumn (g_currentloc
, 0);
4219 if (fileloc_isSpecialFile (g_currentloc
))
4221 gc
.inDerivedFile
= TRUE
;
4224 if (filelocStack_popPushFile (gc
.locstack
, g_currentloc
))
4226 int maxdepth
= context_getValue (FLG_INCLUDENEST
);
4228 if (filelocStack_size (gc
.locstack
) > maxdepth
)
4230 int depth
= filelocStack_includeDepth (gc
.locstack
);
4232 if (depth
> maxdepth
)
4236 message ("Maximum include nesting depth "
4237 "(%d, current depth %d) exceeded",
4240 filelocStack_nextTop (gc
.locstack
)))
4242 filelocStack_printIncludes (gc
.locstack
);
4248 g_currentloc
= fileloc_create (fid
, lineno
, 1);
4250 context_enterFileAux ();
4254 void context_enterIterDef (/*@observer@*/ uentry le
)
4256 context_enterMacro (le
);
4257 gc
.acct
= typeIdSet_subtract (gc
.facct
, gc
.nacct
);
4258 gc
.kind
= CX_ITERDEF
;
4261 void context_enterIterEnd (/*@observer@*/ uentry le
)
4263 context_enterMacro (le
);
4264 gc
.kind
= CX_ITEREND
;
4268 context_destroyMod (void)
4269 /*@globals killed gc@*/
4274 ctype_destroyMod ();
4277 fileTable_free (gc
.ftab
);
4278 gc
.ftab
= fileTable_undefined
;
4280 filelocStack_free (gc
.locstack
);
4283 macrocache_free (gc
.mc
);
4285 /* evans 2002-07-12: not reported because of reldef */
4286 for (i
= 0; i
< gc
.nmods
; i
++)
4288 cstring_free (gc
.moduleaccess
[i
].file
);
4291 sfree (gc
.moduleaccess
);
4294 fileloc_free (gc
.saveloc
); gc
.saveloc
= fileloc_undefined
;
4295 fileloc_free (gc
.pushloc
); gc
.pushloc
= fileloc_undefined
;
4298 sRefSetList_free (gc
.modrecs
);
4300 flagMarkerList_free (gc
.markers
);
4302 messageLog_free (gc
.msgLog
);
4304 clauseStack_free (gc
.clauses
);
4307 cstring_free (gc
.msgAnnote
);
4308 globSet_free (gc
.globs_used
);
4309 metaStateTable_free (gc
.stateTable
);
4310 annotationTable_free (gc
.annotTable
);
4317 bool context_msgBoolInt (void)
4319 return context_flagOn (FLG_BOOLINT
, g_currentloc
);
4322 bool context_msgCharInt (void)
4324 return context_flagOn (FLG_CHARINT
, g_currentloc
);
4327 bool context_msgEnumInt (void)
4329 return context_flagOn (FLG_ENUMINT
, g_currentloc
);
4332 bool context_msgLongInt (void)
4334 return context_flagOn (FLG_LONGINT
, g_currentloc
);
4337 bool context_msgShortInt (void)
4339 return context_flagOn (FLG_SHORTINT
, g_currentloc
);
4342 bool context_msgPointerArith (void)
4344 return context_flagOn (FLG_POINTERARITH
, g_currentloc
);
4347 bool context_msgStrictOps (void)
4349 return context_flagOn (FLG_STRICTOPS
, g_currentloc
);
4352 bool context_msgLh (void)
4354 return gc
.flags
[FLG_DOLH
];
4357 void context_pushLoc (void)
4359 fileloc_free (gc
.pushloc
);
4360 gc
.pushloc
= gc
.saveloc
;
4361 gc
.saveloc
= fileloc_undefined
;
4364 void context_popLoc (void)
4366 gc
.saveloc
= fileloc_update (gc
.saveloc
, gc
.pushloc
);
4369 bool context_inGlobalScope (void)
4371 return (usymtab_inFileScope() || usymtab_inGlobalScope ());
4374 bool context_inInnerScope (void)
4376 return (gc
.kind
== CX_INNER
);
4379 void context_setProtectVars (void)
4381 gc
.protectVars
= TRUE
;
4384 bool context_anyErrors (void)
4386 return (gc
.numerrors
> 0);
4389 void context_hasError (void)
4392 DPRINTF (("num errors: %d", gc
.numerrors
));
4395 int context_numErrors (void)
4397 return gc
.numerrors
;
4400 bool context_neednl (void)
4405 void context_setNeednl (void)
4410 int context_getExpect (void)
4412 return (context_getValue (FLG_EXPECT
));
4415 int context_getLCLExpect (void)
4417 return (context_getValue (FLG_LCLEXPECT
));
4420 int context_getLimit (void)
4422 return (context_getValue (FLG_LIMIT
));
4425 bool context_unlimitedMessages (void)
4427 return (context_getLimit () < 0);
4430 void context_releaseVars (void)
4432 llassert (gc
.protectVars
);
4433 gc
.protectVars
= FALSE
;
4436 void context_sizeofReleaseVars (void)
4438 /* If there is a nested sizeof, this might not hold:
4439 llassert (gc.protectVars);
4442 gc
.protectVars
= FALSE
;
4445 bool context_inProtectVars (void)
4447 return (gc
.protectVars
);
4451 void context_hideShowscan (void)
4453 gc
.flags
[FLG_SHOWSCAN
] = FALSE
;
4456 void context_unhideShowscan (void)
4458 gc
.flags
[FLG_SHOWSCAN
] = TRUE
;
4460 # endif /* DEADCODE */
4462 bool context_inHeader (void)
4464 return (gc
.inheader
);
4467 fileTable
context_fileTable (void)
4472 cstring
context_tmpdir (void)
4474 return (context_getString (FLG_TMPDIR
));
4477 messageLog
context_messageLog (void)
4482 bool context_inMacroFunction (void)
4484 return (gc
.kind
== CX_MACROFCN
);
4487 bool context_inMacroConstant (void)
4489 return (gc
.kind
== CX_MACROCONST
);
4492 bool context_inUnknownMacro (void)
4494 return (gc
.kind
== CX_UNKNOWNMACRO
);
4497 void context_setShownFunction (void)
4499 gc
.showfunction
= FALSE
;
4502 bool context_doDump (void)
4504 return cstring_isNonEmpty (context_getString (FLG_DUMP
));
4507 bool context_doMerge (void)
4509 return cstring_isNonEmpty (context_getString (FLG_MERGE
));
4512 cstring
context_getDump (void)
4514 return context_getString (FLG_DUMP
);
4517 cstring
context_getMerge (void)
4519 return context_getString (FLG_MERGE
);
4522 bool context_inLCLLib (void)
4524 return (gc
.kind
== CX_LCLLIB
);
4528 /*drl add these 3/5/2003*/
4529 static bool inSizeof
= FALSE
;
4531 bool context_inSizeof (void)
4536 void context_enterSizeof (void)
4538 DPRINTF((message("context_enterSizeof ") ) );
4542 void context_leaveSizeof (void)
4544 DPRINTF((message("context_leaveSizeof ") ));
4547 /*end function added 3/5/2003*/
4550 bool context_inImport (void)
4552 return (gc
.inimport
);
4555 void context_enterImport (void)
4560 void context_leaveImport (void)
4562 gc
.inimport
= FALSE
;
4565 bool context_inMacro (void)
4567 return (gc
.kind
== CX_MACROFCN
|| gc
.kind
== CX_MACROCONST
4568 || gc
.kind
== CX_UNKNOWNMACRO
4569 || gc
.kind
== CX_ITERDEF
|| gc
.kind
== CX_ITEREND
);
4572 bool context_inIterDef (void)
4574 return (gc
.kind
== CX_ITERDEF
);
4577 bool context_inIterEnd (void)
4579 return (gc
.kind
== CX_ITEREND
);
4582 int context_getLinesProcessed (void)
4584 return (gc
.linesprocessed
);
4587 int context_getSpecLinesProcessed (void)
4589 return (gc
.speclinesprocessed
);
4592 void context_processedSpecLine (void)
4594 gc
.speclinesprocessed
++;
4597 void context_resetSpecLines (void)
4599 gc
.speclinesprocessed
= 0;
4603 bool context_inGlobalContext (void)
4605 return (gc
.kind
== CX_GLOBAL
);
4608 static void context_quietExitScopes (void)
4611 ** Try to restore the global scope (after an error).
4614 while (!usymtab_inFileScope ())
4616 usymtab_quietExitScope (g_currentloc
);
4619 gc
.cont
.glob
= TRUE
;
4620 gc
.kind
= CX_GLOBAL
;
4623 void context_checkGlobalScope (void)
4625 if (gc
.kind
!= CX_GLOBAL
)
4627 if (context_inMacro ())
4629 ; /* evans 2001-10-14: Okay to be in a macro here! */
4633 llcontbug (message ("Not in global scope as expected: %q", context_unparse ()));
4634 context_quietExitScopes ();
4639 void context_setFileId (fileId s
)
4641 g_currentloc
= fileloc_updateFileId (g_currentloc
, s
);
4644 bool context_setBoolName (void)
4646 return (!cstring_equalLit (context_getString (FLG_BOOLTYPE
),
4650 cstring
context_printBoolName (void)
4652 if (context_setBoolName ())
4654 return context_getBoolName ();
4658 return cstring_makeLiteralTemp ("boolean");
4662 cstring
context_getBoolName (void)
4664 return (context_getString (FLG_BOOLTYPE
));
4667 cstring
context_getFalseName (void)
4669 return (context_getString (FLG_BOOLFALSE
));
4672 cstring
context_getTrueName (void)
4674 return (context_getString (FLG_BOOLTRUE
));
4677 cstring
context_getLarchPath (void)
4679 return (context_getString (FLG_LARCHPATH
));
4682 cstring
context_getLCLImportDir (void)
4684 return (context_getString (FLG_LCLIMPORTDIR
));
4687 static void context_setJustPopped (void)
4689 gc
.justpopped
= TRUE
;
4692 void context_clearJustPopped (void)
4694 gc
.justpopped
= FALSE
;
4697 bool context_justPopped (void)
4699 return (gc
.justpopped
);
4702 void context_setMacroMissingParams (void)
4704 gc
.macroMissingParams
= TRUE
;
4707 void context_resetMacroMissingParams (void)
4709 gc
.macroMissingParams
= FALSE
;
4712 bool context_isMacroMissingParams (void)
4714 return (gc
.macroMissingParams
);
4718 void context_showFilelocStack (void)
4720 filelocStack_printIncludes (gc
.locstack
);
4723 metaStateTable
context_getMetaStateTable (void)
4725 return gc
.stateTable
;
4727 # endif /* DEADCODE */
4729 metaStateInfo
context_lookupMetaStateInfo (cstring key
)
4731 return metaStateTable_lookup (gc
.stateTable
, key
);
4734 /*@null@*/ annotationInfo
context_lookupAnnotation (cstring annot
)
4736 return annotationTable_lookup (gc
.annotTable
, annot
);
4739 void context_addAnnotation (annotationInfo info
)
4741 if (annotationTable_contains (gc
.annotTable
, annotationInfo_getName (info
)))
4745 message ("Duplicate annotation declaration: %s", annotationInfo_getName (info
)),
4746 annotationInfo_getLoc (info
));
4748 annotationInfo_free (info
);
4752 annotationTable_insert (gc
.annotTable
, info
);
4756 void context_addMetaState (cstring mname
, metaStateInfo msinfo
)
4758 if (metaStateTable_contains (gc
.stateTable
, mname
))
4762 message ("Duplicate metastate declaration: %s", mname
),
4763 metaStateInfo_getLoc (msinfo
));
4764 cstring_free (mname
);
4765 metaStateInfo_free (msinfo
);
4769 DPRINTF (("Adding meta state: %s", mname
));
4770 metaStateTable_insert (gc
.stateTable
, mname
, msinfo
);
4774 valueTable
context_createValueTable (sRef s
, stateInfo info
)
4776 if (metaStateTable_size (gc
.stateTable
) > 0)
4778 valueTable res
= valueTable_create (metaStateTable_size (gc
.stateTable
));
4779 /* should use smaller value... */
4780 DPRINTF (("Value table for: %s", sRef_unparse (s
)));
4782 metaStateTable_elements (gc
.stateTable
, msname
, msi
)
4784 mtContextNode context
= metaStateInfo_getContext (msi
);
4786 if (mtContextNode_matchesRefStrict (context
, s
))
4788 DPRINTF (("Create: %s", metaStateInfo_unparse (msi
)));
4789 llassert (cstring_equal (msname
, metaStateInfo_getName (msi
)));
4793 cstring_copy (metaStateInfo_getName (msi
)),
4794 stateValue_createImplicit (metaStateInfo_getDefaultValue (msi
, s
),
4795 stateInfo_copy (info
)));
4799 DPRINTF (("No match: %s", metaStateInfo_unparse (msi
)));
4802 end_metaStateTable_elements
;
4804 stateInfo_free (info
);
4805 DPRINTF (("Value table: %s", valueTable_unparse (res
)));
4810 stateInfo_free (info
);
4811 return valueTable_undefined
;
4815 valueTable
context_createGlobalMarkerValueTable (stateInfo info
)
4817 if (metaStateTable_size (gc
.stateTable
) > 0)
4819 valueTable res
= valueTable_create (metaStateTable_size (gc
.stateTable
));
4820 /* should use smaller value... */
4822 metaStateTable_elements (gc
.stateTable
, msname
, msi
)
4824 /* only add global...*/
4825 DPRINTF (("Create: %s", metaStateInfo_unparse (msi
)));
4826 llassert (cstring_equal (msname
, metaStateInfo_getName (msi
)));
4828 valueTable_insert (res
,
4829 cstring_copy (metaStateInfo_getName (msi
)),
4830 stateValue_create (metaStateInfo_getDefaultGlobalValue (msi
),
4831 stateInfo_copy (info
)));
4833 end_metaStateTable_elements
;
4835 stateInfo_free (info
);
4836 DPRINTF (("Value table: %s", valueTable_unparse (res
)));
4841 stateInfo_free (info
);
4842 return valueTable_undefined
;
4846 constraintList
context_getImplicitFcnConstraints (uentry ue
)
4848 constraintList ret
= constraintList_makeNew ();
4849 uentryList params
= uentry_getParams (ue
);
4851 uentryList_elements (params
, el
)
4853 DPRINTF (("setImplicitfcnConstraints doing: %s", uentry_unparse(el
)));
4855 if (uentry_isElipsisMarker (el
))
4861 sRef s
= uentry_getSref (el
);
4863 DPRINTF (("Trying: %s", sRef_unparse (s
)));
4865 if (ctype_isPointer (sRef_getType (s
)))
4867 constraint c
= constraint_makeSRefWriteSafeInt (s
, 0);
4868 ret
= constraintList_add (ret
, c
);
4870 /*drl 10/23/2002 added support for out*/
4872 if (!uentry_isOut(el
))
4874 c
= constraint_makeSRefReadSafeInt (s
, 0);
4875 ret
= constraintList_add (ret
, c
);
4880 DPRINTF (("%s is NOT a pointer", sRef_unparseFull (s
)));
4883 } end_uentryList_elements
;
4885 DPRINTF (("Returns ==> %s", constraintList_unparse (ret
)));