]> andersk Git - splint.git/blame - src/context.c
Added support for or constraints.
[splint.git] / src / context.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
3** Copyright (C) 1994-2000 University of Virginia,
4** Massachusetts Institute of Technology
5**
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.
10**
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.
15**
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.
19**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** context.c
26*/
27/*
28 * Modified by Herbert 04/19/97:
29 * - added include for new header portab.h containing OS dependent stuff.
30 * - changed occurrances of '/' as path delimiters to macro from portab.h
31 * - changed the handling of the tmp directory -- will no longer always be
32 * ".", if possible, environment variables "TMP" or, if not set, "TMP",
33 * or, if not set "." will be used.
34 */
35
36# include "lclintMacros.nf"
37# include "llbasic.h"
38
39# ifndef NOLCL
40# include "usymtab_interface.h"
41# endif
42
43# include "exprChecks.h"
44# include "filelocStack.h"
45# include "fileIdList.h"
46# include "llmain.h"
47# include "intSet.h"
48# include "osd.h"
49# include "portab.h"
50
51extern /*@external@*/ int yydebug;
52
53typedef struct
54{
55 cstring file;
56 typeIdSet daccess ;
57} maccesst;
58
59typedef enum {
60 CX_GLOBAL, CX_INNER,
61 CX_FUNCTION, CX_FCNDECL,
62 CX_MACROFCN, CX_MACROCONST, CX_UNKNOWNMACRO,
63 CX_ITERDEF, CX_ITEREND,
64 CX_LCL, CX_LCLLIB
65} kcontext;
66
67static struct _context
68{
69 int linesprocessed;
70 int speclinesprocessed;
71
72 flagMarkerList markers;
73
74 /*
75 ** used to record state where a macro must match a function name
76 ** (i.e., no params were listed in the macro definition
77 */
78
79 bool macroMissingParams BOOLBITS;
80 bool preprocessing BOOLBITS;
81 bool incommandline BOOLBITS;
82 bool insuppressregion BOOLBITS;
83 bool inDerivedFile BOOLBITS;
84 bool instandardlib BOOLBITS;
85 bool inimport BOOLBITS;
86 bool inheader BOOLBITS;
87 bool inmacrocache BOOLBITS;
88 bool protectVars BOOLBITS;
89 bool neednl BOOLBITS;
90 bool showfunction BOOLBITS;
91 bool savedFlags BOOLBITS;
92 bool justpopped BOOLBITS;
93 bool anyExports BOOLBITS;
94
95 flagcode library;
96
97 ynm isNullGuarded;
98 fileloc saveloc;
99 fileloc pushloc;
100
101 clauseStack clauses;
102 clause inclause;
103
104 int numerrors;
105
106 filelocStack locstack;
107 fileTable ftab;
108 cstring msgAnnote;
109 /*@observer@*/ sRef aliasAnnote;
110 /*@observer@*/ sRef aliasAnnoteAls;
111 messageLog msgLog;
112
113 macrocache mc;
114 /*@observer@*/ sRefSet mods;
115
116 /* file access types */
117 typeIdSet facct;
118
119 /* local access types (this function) */
120 typeIdSet acct;
121
122 /* no access types (@noaccess) */
123 typeIdSet nacct;
124
125 /*@observer@*/ globSet globs;
126 /*@only@*/ globSet globs_used;
127
128 int nmods;
129 int maxmods;
130 /*@reldef@*/ maccesst *moduleaccess; /* Not defined is nmods == 0. */
131
132 kcontext kind;
133
134 ctype boolType;
135
136 bool flags[NUMFLAGS];
137 bool saveflags[NUMFLAGS];
138 bool setGlobally[NUMFLAGS];
139 bool setLocally[NUMFLAGS];
140
141 int values[NUMVALUEFLAGS];
142 int counters[NUMVALUEFLAGS];
143
144 o_cstring strings[NUMSTRINGFLAGS];
145 sRefSetList modrecs;
146
147 union
148 {
149 bool glob;
150 int cdepth;
151 /*@dependent@*/ /*@exposed@*/ uentry fcn;
152 } cont;
153} gc;
154
155static /*@exposed@*/ cstring context_exposeString (flagcode p_flag) ;
156static void context_restoreFlagSettings (void) /*@modifies gc@*/ ;
157static void context_saveFlagSettings (void) /*@modifies gc@*/ ;
158static void context_exitClauseAux (exprNode p_pred, exprNode p_tbranch)
159 /*@modifies gc@*/ ;
160static void context_exitClauseSimp (void) /*@modifies gc@*/ ;
161static void context_exitClausePlain (void) /*@modifies gc@*/ ;
162static void context_setJustPopped (void) /*@modifies gc.justpopped@*/ ;
163static void context_setValue (flagcode p_flag, int p_val) /*@modifies gc.flags@*/ ;
90bc41f7 164/*drl fix static */ void context_setFlag (flagcode p_f, bool p_b)
616915dd 165 /*@modifies gc.flags@*/ ;
166
167static void
168 context_setFlagAux (flagcode p_f, bool p_b, bool p_inFile, bool p_isRestore)
169 /*@modifies gc.flags@*/ ;
170
171static void context_restoreFlag (flagcode p_f) /*@modifies gc.flags@*/ ;
172
173/*@+enumindex@*/
174
175cstring context_unparseFlagMarkers ()
176{
177 return (flagMarkerList_unparse (gc.markers));
178}
179
180void context_setPreprocessing (void)
181{
182 llassert (!gc.preprocessing);
183 gc.preprocessing = TRUE;
184}
185
186void context_clearPreprocessing (void)
187{
188 llassert (gc.preprocessing);
189 gc.preprocessing = FALSE;
190}
191
192bool context_isPreprocessing (void)
193{
194 return gc.preprocessing;
195}
196
197void context_setInCommandLine (void)
198{
199 llassert (!gc.incommandline);
200 gc.incommandline = TRUE;
201}
202
203void context_clearInCommandLine (void)
204{
205 llassert (gc.incommandline);
206 gc.incommandline = FALSE;
207}
208
209bool context_isInCommandLine (void)
210{
211 return gc.incommandline;
212}
213
214static
215void pushClause (clause c) /*@modifies gc.clauses, gc.inclause@*/
216{
217 gc.inclause = c;
218 clauseStack_push (gc.clauses, c);
219
220 if (clause_isConditional (c)
221 && context_getFlag (FLG_CONTROLNESTDEPTH))
222 {
223 int maxdepth = context_getValue (FLG_CONTROLNESTDEPTH);
224 int depth = clauseStack_controlDepth (gc.clauses);
225
226 if (depth == maxdepth + 1)
227 {
228 voptgenerror
229 (FLG_CONTROLNESTDEPTH,
230 message ("Maximum control nesting depth "
231 "(%d) exceeded",
232 maxdepth),
233 g_currentloc);
234 }
235 }
236}
237
238static
239clause topClause (clauseStack s) /*@*/
240{
241 if (clauseStack_isEmpty (s)) return NOCLAUSE;
242 return ((clause) clauseStack_top (s));
243}
244
245void
246context_addMacroCache (/*@only@*/ cstring def)
247{
248 macrocache_addEntry (gc.mc, fileloc_copy (g_currentloc), def);
249}
250
251void
252context_addComment (/*@only@*/ cstring def)
253{
254 macrocache_addComment (gc.mc, fileloc_copy (g_currentloc), def);
255}
256
257/*
258** returns TRUE is fl is in ignore region, or region where -code
259**
260** the logic is fuzzy...
261*/
262
263static bool
264context_inSuppressFlagZone (fileloc fl, flagcode code)
265{
266 ynm ret = flagMarkerList_suppressError (gc.markers, code, fl);
267 bool res = FALSE;
268
269 if (ynm_isMaybe (ret))
270 {
271 /*
272 ** whas is dis?
273 */
274
275 if (gc.savedFlags)
276 {
277 res = !gc.saveflags[code];
278 }
279 else
280 {
281 res = !context_getFlag (code);
282 }
283 }
284 else
285 {
286 res = ynm_toBoolStrict (ret);
287 }
288
289 return res;
290}
291
292static bool
293context_suppressSystemMsg (fileloc fl)
294{
295 if (context_getFlag (FLG_SYSTEMDIRERRORS))
296 {
297 return FALSE;
298 }
299 else
300 {
301 return (fileloc_isSystemFile (fl));
302 }
303}
304
305bool
306context_suppressFlagMsg (flagcode flag, fileloc fl)
307{
308 if (context_suppressSystemMsg (fl))
309 {
310 return TRUE;
311 }
312
313 /* want same object compare here */
314
315 if (fileloc_equal (fl, g_currentloc) || gc.inDerivedFile)
316 {
317 return (!context_getFlag (flag)
318 || context_inSuppressRegion ()
319 || context_inSuppressZone (fl)
320 || (gc.inDerivedFile && context_inSuppressFlagZone (fl, flag)));
321 }
322 else
323 {
324 return (context_inSuppressFlagZone (fl, flag));
325 }
326}
327
328bool
329context_suppressNotFlagMsg (flagcode flag, fileloc fl)
330{
331
332 if (context_suppressSystemMsg (fl))
333 {
334 return TRUE;
335 }
336
337 /*@access fileloc@*/
338 if (fl == g_currentloc)
339 /*@noaccess fileloc@*/
340 {
341 return (context_getFlag (flag) || context_inSuppressRegion ());
342 }
343 else
344 {
345 /* for now... */
346 return (context_getFlag (flag) || context_inSuppressRegion ());
347 }
348}
349
350bool
351context_inSuppressZone (fileloc fl)
352{
353 if (context_suppressSystemMsg (fl))
354 {
355 return TRUE;
356 }
357
358 return (flagMarkerList_inIgnore (gc.markers, fl));
359}
360
361bool
362context_inSuppressRegion (void)
363{
364 return (gc.insuppressregion);
365}
366
367void
368context_enterSuppressRegion (void)
369{
370 if (gc.insuppressregion)
371 {
372 gc.insuppressregion = FALSE; /* get this msg! */
373 llmsg (message
374 ("%q: New ignore errors region entered while in ignore errors region",
375 fileloc_unparse (g_currentloc)));
376 }
377
378 gc.insuppressregion = TRUE;
379 flagMarkerList_add (gc.markers, flagMarker_createIgnoreOn (g_currentloc));
380}
381
382static void
383context_addFlagMarker (flagcode code, ynm set)
384{
385 flagMarkerList_add (gc.markers,
386 flagMarker_createLocalSet (code, set, g_currentloc));
387}
388
389void
390context_enterSuppressLine (int count)
391{
392 fileloc nextline = fileloc_copy (g_currentloc);
393
394 flagMarkerList_add (gc.markers,
395 flagMarker_createIgnoreCount (count, g_currentloc));
396
397 fileloc_nextLine (nextline);
398 flagMarkerList_add (gc.markers,
399 flagMarker_createIgnoreOff (nextline));
400 fileloc_free (nextline);
401}
402
403void context_checkSuppressCounts (void)
404{
405 if (context_getFlag (FLG_SUPCOUNTS))
406 {
407 flagMarkerList_checkSuppressCounts (gc.markers);
408 }
409}
410
411void context_incLineno (void)
412{
413 gc.linesprocessed++;
414 incLine ();
415}
416
417void
418context_exitSuppressRegion (void)
419{
420 if (!gc.insuppressregion)
421 {
422 llerrorlit (FLG_SYNTAX,
423 "End ignore errors in region while not ignoring errors");
424 }
425
426 gc.insuppressregion = FALSE;
427 flagMarkerList_add (gc.markers, flagMarker_createIgnoreOff (g_currentloc));
428}
429
430# ifndef NOLCL
431void
432context_enterLCLfile (void)
433{
434 gc.kind = CX_LCL;
435 gc.facct = typeIdSet_emptySet ();
436}
437# endif
438
439static void
440addModuleAccess (/*@only@*/ cstring fname, typeIdSet mods)
441{
442 int i;
443
444 for (i = 0; i < gc.nmods; i++)
445 {
446 if (cstring_equal (gc.moduleaccess[i].file, fname))
447 {
448 gc.moduleaccess[i].daccess = typeIdSet_union (gc.moduleaccess[i].daccess, mods);
449 cstring_free (fname);
450 return;
451 }
452 }
453
454 if (gc.nmods == gc.maxmods)
455 {
456 maccesst *oldmods;
457
458 gc.maxmods = gc.maxmods + DEFAULTMAXMODS;
459 oldmods = gc.moduleaccess;
460
461 gc.moduleaccess = (maccesst *) dmalloc (sizeof (*gc.moduleaccess) * (gc.maxmods));
462
463 for (i = 0; i < gc.nmods; i++)
464 {
465 gc.moduleaccess[i] = oldmods[i];
466 }
467
468 sfree (oldmods);
469 }
470
471 gc.moduleaccess[gc.nmods].file = fname;
472 gc.moduleaccess[gc.nmods].daccess = mods;
473
474 gc.nmods++;
475}
476
477static void
478insertModuleAccess (cstring fname, typeId t)
479{
480 int i;
481
482 for (i = 0; i < gc.nmods; i++)
483 {
484 if (cstring_equal (gc.moduleaccess[i].file, fname))
485 {
486 gc.moduleaccess[i].daccess = typeIdSet_insert (gc.moduleaccess[i].daccess, t);
487 break;
488 }
489 }
490
491 addModuleAccess (cstring_copy (fname), typeIdSet_single (t));
492}
493
494# ifndef NOLCL
495void
496context_exitLCLfile (void)
497{
498 if (gc.kind != CX_LCLLIB)
499 {
500 char *lclname =
501 removeExtension (cstring_toCharsSafe
502 (fileName (currentFile ())), ".lcl");
503
504 addModuleAccess (cstring_fromCharsO (removePath (lclname)), gc.facct);
505
506 mstring_free (lclname);
507 }
508
509 gc.kind = CX_LCL;
510 gc.kind = CX_GLOBAL;
511 gc.facct = typeIdSet_emptySet ();
512}
513# endif
514
515void
516context_dumpModuleAccess (FILE *fout)
517{
518 int i = 0;
519
520 for (i = 0; i < gc.nmods; i++)
521 {
522 cstring td = typeIdSet_dump (gc.moduleaccess[i].daccess);
523
524 fprintf (fout, "%s#%s@\n",
525 cstring_toCharsSafe (gc.moduleaccess[i].file),
526 cstring_toCharsSafe (td));
527
528 cstring_free (td);
529 }
530}
531
532bool context_usingPosixLibrary ()
533{
534 return (gc.library == FLG_POSIXLIB
535 || gc.library == FLG_POSIXSTRICTLIB
536 || gc.library == FLG_UNIXLIB
537 || gc.library == FLG_UNIXSTRICTLIB);
538}
539
540bool context_usingAnsiLibrary ()
541{
542 return (gc.library != FLG_NOLIB);
543}
544
545flagcode context_getLibrary ()
546{
547 return gc.library;
548}
549
550void context_setLibrary (flagcode code)
551{
552 gc.library = code;
553}
554
555/*@observer@*/ char *context_selectedLibrary ()
556{
557 switch (gc.library)
558 {
559 case FLG_STRICTLIB:
560 return LLSTRICTLIBS_NAME;
561 case FLG_POSIXLIB:
562 return LLPOSIXLIBS_NAME;
563 case FLG_POSIXSTRICTLIB:
564 return LLPOSIXSTRICTLIBS_NAME;
565 case FLG_UNIXLIB:
566 return LLUNIXLIBS_NAME;
567 case FLG_UNIXSTRICTLIB:
568 return LLUNIXSTRICTLIBS_NAME;
569 case FLG_ANSILIB:
570 return LLSTDLIBS_NAME;
571 BADDEFAULT;
572 }
573}
574
575
576void
577context_loadModuleAccess (FILE *in)
578{
579 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
580 char *lasts = s;
581 char *name = mstring_create (MAX_NAME_LENGTH);
582 char *oname = name;
583# ifndef NOFREE
584 char *os = s;
585# endif
586
587 while (fgets (s, MAX_DUMP_LINE_LENGTH, in) != NULL
588 && *s == ';')
589 {
590 ;
591 }
592
593 while (s != NULL && *s != ';' && *s != '\0')
594 {
595 name = oname;
596
597 while (*s != '#' && *s != '\0')
598 {
599 *name++ = *s++;
600 }
601
602 *name = '\0';
603
604 if (*s != '#')
605 {
606 llcontbug (message ("context_loadModuleAccess: bad library line: %s\n",
607 cstring_fromChars (s)));
608 break;
609 }
610
611 s++;
612
613 addModuleAccess (cstring_copy (cstring_fromChars (oname)),
614 typeIdSet_undump (&s));
615
616 (void) fgets (s, MAX_DUMP_LINE_LENGTH, in);
617 llassert (s != lasts);
618 lasts = s;
619 }
620
621 sfree (oname);
622# ifndef NOFREE
623 sfree (os);
624# endif
625}
626
627typeIdSet context_fileAccessTypes (void)
628{
629 return gc.facct;
630}
631
632void
633context_resetModeFlags (void)
634{
635
636 allFlagCodes (code)
637 {
638 if (flagcode_isModeFlag (code))
639 {
640 context_setFlag (code, FALSE);
641 }
642 } end_allFlagCodes;
643
644 }
645
646/*
647** resetAllFlags
648**
649** Set all flags to FALSE, except for a few which are
650** true by default.
651**
652** Set all values and strings to appropriate defaults.
653** Set all counters to 0.
654*/
655
656static void
657conext_resetAllCounters (void)
658{
659 int i;
660
661 for (i = 0; i < NUMVALUEFLAGS; i++)
662 {
663 gc.counters[i] = 0;
664 }
665}
666
667void
668context_resetAllFlags (void)
669{
670 allFlagCodes (code)
671 {
672 gc.flags[code] = FALSE;
673
674 if (flagcode_hasValue (code))
675 {
676 int val = 0;
677
678 /*@-loopswitchbreak@*/
679 switch (code)
680 {
681 case FLG_LIMIT:
682 val = DEFAULT_LIMIT; break;
683 case FLG_LINELEN:
684 val = DEFAULT_LINELEN; break;
685 case FLG_EXTERNALNAMELEN:
686 val = DEFAULT_EXTERNALNAMELEN; break;
687 case FLG_INTERNALNAMELEN:
688 val = DEFAULT_INTERNALNAMELEN; break;
689 case FLG_COMMENTCHAR:
690 val = (int) DEFAULT_COMMENTCHAR; break;
691 case FLG_CONTROLNESTDEPTH:
692 val = (int) DEFAULT_CONTROLNESTDEPTH; break;
693 case FLG_STRINGLITERALLEN:
694 val = (int) DEFAULT_STRINGLITERALLEN; break;
695 case FLG_INCLUDENEST:
696 val = (int) DEFAULT_INCLUDENEST; break;
697 case FLG_NUMSTRUCTFIELDS:
698 val = (int) DEFAULT_NUMSTRUCTFIELDS; break;
699 case FLG_NUMENUMMEMBERS:
700 val = (int) DEFAULT_NUMENUMMEMBERS; break;
701 case FLG_EXPECT:
702 case FLG_LCLEXPECT:
703 break;
704 default:
705 llbug (message ("Bad value flag: %s", flagcode_unparse (code)));
706 }
707 /*@=loopswitchbreak@*/
708
709 context_setValue (code, val);
710 }
711 else if (flagcode_hasString (code))
712 {
713 cstring val = cstring_undefined;
714
715 switch (code)
716 { /*@-loopswitchbreak@*/
717 case FLG_LARCHPATH:
718 {
719 char *larchpath = osd_getEnvironmentVariable (LARCH_PATH);
720
721 if (larchpath != NULL)
722 {
723 val = cstring_fromCharsNew (larchpath);
724 }
725 else
726 {
727 val = cstring_makeLiteral (DEFAULT_LARCHPATH);
728 }
729
730 break;
731 }
732 case FLG_LCLIMPORTDIR:
733 {
734 val = cstring_fromCharsNew (osd_getEnvironment (LCLIMPORTDIR, DEFAULT_LCLIMPORTDIR));
735 break;
736 }
737 case FLG_TMPDIR:
738# if defined(OS2) || defined(MSDOS) || defined(WIN32)
739 {
740 char *env = osd_getEnvironmentVariable ("TMP");
741
742 if (env == NULL)
743 {
744 env = osd_getEnvironmentVariable ("TEMP");
745 }
746
747 val = cstring_makeLiteral (env != NULL ? env : DEFAULT_TMPDIR);
748 }
749# else
750 val = cstring_makeLiteral (DEFAULT_TMPDIR);
751# endif /* !defined(OS2) && !defined(MSDOS) */
752
753 break;
754 case FLG_BOOLTYPE:
755 val = cstring_makeLiteral (DEFAULT_BOOLTYPE); break;
756 case FLG_BOOLFALSE:
757 val = cstring_makeLiteral ("FALSE"); break;
758 case FLG_BOOLTRUE:
759 val = cstring_makeLiteral ("TRUE"); break;
760 case FLG_MACROVARPREFIX:
761 val = cstring_makeLiteral ("m_"); break;
762 case FLG_SYSTEMDIRS:
763 val = cstring_makeLiteral (DEFAULT_SYSTEMDIR); break;
764 default:
765 break;
766 } /*@=loopswitchbreak@*/
767
768 context_setString (code, val);
769 }
770 else
771 {
772 ; /* nothing to set */
773 }
774 } end_allFlagCodes;
775
776 /*
777 ** These flags are true by default.
778 */
779
780 gc.flags[FLG_MODIFIES] = TRUE;
781 gc.flags[FLG_NESTCOMMENT] = TRUE;
782 gc.flags[FLG_GLOBALS] = TRUE;
783 gc.flags[FLG_FULLINITBLOCK] = TRUE;
784 gc.flags[FLG_LIKELYBOOL] = TRUE;
785 gc.flags[FLG_ZEROPTR] = TRUE;
786 gc.flags[FLG_NUMLITERAL] = TRUE;
787 gc.flags[FLG_DUPLICATEQUALS] = TRUE;
788 gc.flags[FLG_SKIPANSIHEADERS] = TRUE;
789 gc.flags[FLG_SKIPPOSIXHEADERS] = TRUE;
790 gc.flags[FLG_SYSTEMDIREXPAND] = TRUE;
791 gc.flags[FLG_UNRECOGCOMMENTS] = TRUE;
792 gc.flags[FLG_CASTFCNPTR] = TRUE;
793 gc.flags[FLG_DOLCS] = TRUE;
794 gc.flags[FLG_USEVARARGS] = TRUE;
795 gc.flags[FLG_MAINTYPE] = TRUE;
796 gc.flags[FLG_SPECMACROS] = TRUE;
797 gc.flags[FLG_REDEF] = TRUE;
798 gc.flags[FLG_MACRONEXTLINE] = TRUE;
799
800 gc.flags[FLG_SIZEOFFORMALARRAY] = TRUE;
801 gc.flags[FLG_FIXEDFORMALARRAY] = TRUE;
802
803 gc.flags[FLG_PREDASSIGN] = TRUE;
804 gc.flags[FLG_MODOBSERVER] = TRUE;
805 gc.flags[FLG_MACROVARPREFIXEXCLUDE] = TRUE;
806 gc.flags[FLG_EXTERNALNAMECASEINSENSITIVE] = TRUE;
807
808 gc.flags[FLG_PARAMIMPTEMP] = TRUE;
809 gc.flags[FLG_RETIMPONLY] = TRUE;
810 gc.flags[FLG_GLOBIMPONLY] = TRUE;
811 gc.flags[FLG_STRUCTIMPONLY] = TRUE;
812 gc.flags[FLG_PREPROC] = TRUE;
813 gc.flags[FLG_NAMECHECKS] = TRUE;
814 gc.flags[FLG_FORMATCODE] = TRUE;
815 gc.flags[FLG_FORMATTYPE] = TRUE;
816 gc.flags[FLG_BADFLAG] = TRUE;
817 gc.flags[FLG_WARNFLAGS] = TRUE;
818 gc.flags[FLG_WARNUNIXLIB] = TRUE;
819 gc.flags[FLG_WARNPOSIX] = TRUE;
820 gc.flags[FLG_SHOWCOL] = TRUE;
821 gc.flags[FLG_SHOWFUNC] = TRUE;
822 gc.flags[FLG_SUPCOUNTS] = TRUE;
823 gc.flags[FLG_HINTS] = TRUE;
824 gc.flags[FLG_SYNTAX] = TRUE;
825 gc.flags[FLG_TYPE] = TRUE;
826 gc.flags[FLG_INCOMPLETETYPE] = TRUE;
827 gc.flags[FLG_ABSTRACT] = TRUE;
828 gc.flags[FLG_ITER] = TRUE;
829 gc.flags[FLG_CONTROL] = TRUE;
830 gc.flags[FLG_UNRECOG] = TRUE;
831 gc.flags[FLG_SYSTEMUNRECOG] = TRUE;
832 gc.flags[FLG_LINTCOMMENTS] = TRUE;
833 gc.flags[FLG_ACCESSCZECH] = TRUE;
834 gc.flags[FLG_ACCESSMODULE] = TRUE;
835 gc.flags[FLG_ACCESSFILE] = TRUE;
836 gc.flags[FLG_MACROVARPREFIX] = TRUE;
837
838 /*
839 ** Changed for version 2.4.
840 */
841
842 gc.flags[FLG_GNUEXTENSIONS] = TRUE;
843
844 /*
845 ** On by default for Win32, but not Unix (to support MS/VC++ error message format).
846 */
847
848# ifdef WIN32
849 gc.flags[FLG_PARENFILEFORMAT] = TRUE;
850# endif
851}
852
853/*
854** C is way-lame, and you can initialize an array to a constant except where
855** it is declared. Hence, a macro is used to set the modeflags.
856*/
857
858/*@notfunction@*/
859# define SETFLAGS() \
860 { int i = 0; while (modeflags[i] != INVALID_FLAG) { \
861 if (!flagcode_isModeFlag (modeflags[i])) \
862 { llbug (message ("not a mode flag: %s", \
863 flagcode_unparse (modeflags[i]))); } \
864 else { context_setFlag (modeflags[i], TRUE); } i++; }}
865
866void
867context_setMode (cstring s)
868{
869 intSet setflags = intSet_new ();
870
871 allFlagCodes (code)
872 {
873 if (flagcode_isModeFlag (code))
874 {
875 if (gc.setGlobally[code])
876 {
877 (void) intSet_insert (setflags, (int) code);
878 }
879 }
880 } end_allFlagCodes;
881
882 if (!intSet_isEmpty (setflags))
883 {
884 cstring rflags = cstring_undefined;
885 int num = 0;
886
887 intSet_elements (setflags, el)
888 {
889 if (cstring_isUndefined (rflags))
890 {
891 rflags = cstring_copy (flagcode_unparse ((flagcode) (el)));
892 }
893 else
894 {
895 rflags = message ("%q, %s", rflags,
896 flagcode_unparse ((flagcode) el));
897 }
898
899 num++;
900 if (num > 4 && intSet_size (setflags) > 6)
901 {
902 rflags = message ("%q, (%d others) ...", rflags,
903 intSet_size (setflags) - num);
904 break;
905 }
906 } end_intSet_elements ;
907
908 voptgenerror (FLG_WARNFLAGS,
909 message ("Setting mode %s after setting mode flags will "
910 "override set values of flags: %s",
911 s, rflags),
912 g_currentloc);
913
914 cstring_free (rflags);
915 }
916
917 intSet_free (setflags);
918
919 context_resetModeFlags ();
920
921 if (cstring_equalLit (s, "standard"))
922 {
923 flagcode modeflags[] =
924 {
925 FLG_ENUMINT, FLG_MACROMATCHNAME,
926 FLG_MACROUNDEF, FLG_RELAXQUALS,
927 FLG_USEALLGLOBS, FLG_CHECKSTRICTGLOBALS,
928 FLG_CHECKSTRICTGLOBALIAS,
929 FLG_CHECKEDGLOBALIAS,
930 FLG_CHECKMODGLOBALIAS,
931 FLG_PREDBOOLOTHERS, FLG_PREDBOOLINT,
932 FLG_PARAMUNUSED, FLG_VARUNUSED, FLG_FUNCUNUSED,
933 FLG_TYPEUNUSED,
934 FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED, FLG_FIELDUNUSED,
935 FLG_PTRNUMCOMPARE, FLG_BOOLCOMPARE, FLG_MUTREP,
936 FLG_NOEFFECT, FLG_IMPTYPE,
937 FLG_RETVALOTHER, FLG_RETVALBOOL, FLG_RETVALINT,
938 FLG_SPECUNDEF, FLG_INCONDEFS, FLG_INCONDEFSLIB,
939 FLG_MATCHFIELDS,
940 FLG_MACROPARAMS, FLG_MACROASSIGN, FLG_SEFPARAMS,
941 FLG_MACROSTMT, FLG_MACROPARENS,
942 FLG_MACROFCNDECL,
943 FLG_MACROCONSTDECL,
944 FLG_MACROREDEF, FLG_INFLOOPS, FLG_UNREACHABLE,
945 FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE, FLG_USEDEF,
946 FLG_FIRSTCASE,
947 FLG_NESTEDEXTERN,
948 FLG_NUMLITERAL,
949 FLG_ZEROBOOL,
950 /* memchecks flags */
951 FLG_NULLDEREF,
952 FLG_NULLSTATE, FLG_NULLASSIGN,
953 FLG_NULLPASS, FLG_NULLRET,
954
955 FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF,
956 FLG_RETSTACK,
957
958 /* memtrans flags */
959 FLG_EXPOSETRANS,
960 FLG_OBSERVERTRANS,
961 FLG_DEPENDENTTRANS,
962 FLG_NEWREFTRANS,
963 FLG_ONLYTRANS,
964 FLG_OWNEDTRANS,
965 FLG_FRESHTRANS,
966 FLG_SHAREDTRANS,
967 FLG_TEMPTRANS,
968 FLG_KEPTTRANS,
969 FLG_REFCOUNTTRANS,
970 FLG_STATICTRANS,
971 FLG_UNKNOWNTRANS,
972 FLG_KEEPTRANS,
973 FLG_IMMEDIATETRANS,
974
975 FLG_EXPORTLOCAL,
976
977 FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
978 FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE,
979 FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
980 FLG_MEMIMPLICIT,
981 FLG_BRANCHSTATE,
982
983 FLG_EVALORDER, FLG_SHADOW, FLG_READONLYSTRINGS,
984 FLG_EXITARG,
985 FLG_IMPCHECKEDSPECGLOBALS,
986 FLG_MODGLOBS, FLG_WARNLINTCOMMENTS,
987 FLG_IFEMPTY, FLG_REALCOMPARE,
988 FLG_BOOLOPS, FLG_PTRNEGATE,
989 FLG_SHIFTSIGNED,
990 INVALID_FLAG } ;
991
992 SETFLAGS ();
993 }
994 else if (cstring_equalLit (s, "weak"))
995 {
996 flagcode modeflags[] =
997 {
998 FLG_BOOLINT, FLG_CHARINT, FLG_FLOATDOUBLE,
999 FLG_ENUMINT, FLG_RELAXQUALS, FLG_FORWARDDECL,
1000 FLG_CHARINDEX, FLG_ABSTVOIDP, FLG_USEALLGLOBS,
1001 FLG_CHARUNSIGNEDCHAR,
1002 FLG_PREDBOOLOTHERS,
1003 FLG_VARUNUSED, FLG_FUNCUNUSED,
1004 FLG_TYPEUNUSED,
1005 FLG_CHECKSTRICTGLOBALS, FLG_MACROMATCHNAME,
1006 FLG_RETVALOTHER,
1007 FLG_IFEMPTY,
1008 FLG_RETSTACK, FLG_PTRNEGATE,
1009 FLG_LONGUNSIGNEDINTEGRAL,
1010 FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL,
1011 FLG_NUMLITERAL,
1012 FLG_CHARINTLITERAL,
1013 FLG_ZEROBOOL,
1014 INVALID_FLAG
1015 } ;
1016
1017 SETFLAGS ();
1018 }
1019 else if (cstring_equalLit (s, "checks"))
1020 {
1021 flagcode modeflags[] =
1022 {
1023 FLG_EXPORTLOCAL, FLG_IMPTYPE,
1024 FLG_CHECKSTRICTGLOBALIAS,
1025 FLG_CHECKEDGLOBALIAS,
1026 FLG_CHECKMODGLOBALIAS,
1027 FLG_UNCHECKEDGLOBALIAS,
1028 FLG_EXITARG, FLG_PTRNUMCOMPARE,
1029 FLG_BOOLCOMPARE, FLG_MACROUNDEF,
1030 FLG_MUSTMOD, FLG_ALLGLOBALS,
1031 FLG_PREDBOOLOTHERS, FLG_PREDBOOLPTR, FLG_PREDBOOLINT,
1032 FLG_USEALLGLOBS, FLG_MUTREP, FLG_RETALIAS,
1033 FLG_RETEXPOSE, FLG_ASSIGNEXPOSE, FLG_CASTEXPOSE,
1034 FLG_FUNCUNUSED, FLG_GLOBALSIMPMODIFIESNOTHING,
1035 FLG_TYPEUNUSED, FLG_FIELDUNUSED, FLG_PARAMUNUSED, FLG_VARUNUSED,
1036 FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED,
1037 FLG_NOEFFECT, FLG_EXPORTHEADER, FLG_EXPORTHEADERVAR,
1038 FLG_RETVALOTHER, FLG_RETVALBOOL, FLG_RETVALINT,
1039 FLG_SPECUNDEF, FLG_IMPCHECKMODINTERNALS,
1040 FLG_DECLUNDEF, FLG_INCONDEFS, FLG_INCONDEFSLIB,
1041 FLG_MATCHFIELDS,
1042 FLG_MACROPARAMS,
1043 FLG_MACROASSIGN,
1044 FLG_DECLPARAMMATCH,
1045 FLG_FCNDEREF,
1046 FLG_FIRSTCASE,
1047 FLG_SEFPARAMS, FLG_SEFUNSPEC, FLG_MACROSTMT, FLG_MACROPARENS,
1048 FLG_MACROCONSTDECL,
1049 FLG_MACROFCNDECL,
1050 FLG_MACROREDEF,
1051 FLG_INFLOOPS, FLG_INFLOOPSUNCON,
1052 FLG_UNREACHABLE,
1053 FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE,
1054 FLG_EVALORDER, FLG_USEDEF,
1055
1056 FLG_NESTEDEXTERN,
1057
1058 /* memchecks flags */
1059
1060 FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
1061 FLG_NULLPASS, FLG_NULLRET,
1062
1063 FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF, FLG_RETSTACK,
1064
1065 /* memtrans flags */
1066 FLG_EXPOSETRANS,
1067 FLG_OBSERVERTRANS,
1068 FLG_DEPENDENTTRANS,
1069 FLG_NEWREFTRANS,
1070 FLG_ONLYTRANS,
1071 FLG_OWNEDTRANS,
1072 FLG_FRESHTRANS,
1073 FLG_SHAREDTRANS,
1074 FLG_TEMPTRANS,
1075 FLG_KEPTTRANS,
1076 FLG_REFCOUNTTRANS,
1077 FLG_STATICTRANS,
1078 FLG_UNKNOWNTRANS,
1079 FLG_STATICINITTRANS,
1080 FLG_UNKNOWNINITTRANS,
1081 FLG_KEEPTRANS,
1082 FLG_IMMEDIATETRANS,
1083 FLG_ONLYUNQGLOBALTRANS,
1084 FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
1085 FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE,
1086 FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
1087 FLG_MEMIMPLICIT,
1088 FLG_BRANCHSTATE,
1089 FLG_NULLPOINTERARITH,
1090 FLG_SHADOW, FLG_DEPARRAYS,
1091 FLG_REDECL, FLG_READONLYSTRINGS, FLG_READONLYTRANS,
1092 FLG_LOOPLOOPBREAK, FLG_SWITCHLOOPBREAK, FLG_MODGLOBS,
1093 FLG_CHECKSTRICTGLOBALS, FLG_IMPCHECKEDSPECGLOBALS,
1094 FLG_MACROMATCHNAME, FLG_WARNLINTCOMMENTS,
1095 FLG_INCLUDENEST, FLG_ANSIRESERVED, FLG_CPPNAMES,
1096 FLG_NOPARAMS, FLG_IFEMPTY, FLG_WHILEEMPTY, FLG_REALCOMPARE,
1097 FLG_BOOLOPS, FLG_SHIFTSIGNED,
1098 INVALID_FLAG } ;
1099
1100 SETFLAGS ();
1101 }
1102 else if (cstring_equalLit (s, "strict"))
1103 {
1104 flagcode modeflags[] =
1105 {
1106 FLG_CHECKSTRICTGLOBALIAS,
1107 FLG_CHECKEDGLOBALIAS,
1108 FLG_CHECKMODGLOBALIAS,
1109 FLG_UNCHECKEDGLOBALIAS,
1110 FLG_MODFILESYSTEM,
1111 FLG_MACROMATCHNAME,
1112 FLG_MACROUNDEF, FLG_MUTREP, FLG_MUSTMOD,
1113 FLG_ALLGLOBALS, FLG_IMPTYPE,
1114 FLG_MODNOMODS, FLG_MODGLOBSUNSPEC, FLG_MODSTRICTGLOBSUNSPEC,
1115 FLG_GLOBUNSPEC, FLG_SIZEOFTYPE,
1116 FLG_EXPORTHEADER, FLG_EXPORTHEADERVAR,
1117 FLG_NOPARAMS, FLG_OLDSTYLE, FLG_EXITARG,
1118 FLG_RETSTACK,
1119 FLG_FCNDEREF,
1120 FLG_ONLYUNQGLOBALTRANS,
1121 FLG_GLOBALSIMPMODIFIESNOTHING,
1122 FLG_PREDBOOLOTHERS, FLG_PREDBOOLPTR, FLG_PREDBOOLINT,
1123 FLG_INTERNALGLOBS, FLG_INTERNALGLOBSNOGLOBS,
1124 FLG_USEALLGLOBS, FLG_RETALIAS,
1125 FLG_MODGLOBS, FLG_MODGLOBSUNSPEC, FLG_MODGLOBSUNCHECKED,
1126 FLG_RETEXPOSE, FLG_ASSIGNEXPOSE, FLG_CASTEXPOSE,
1127 FLG_NOEFFECTUNCON, FLG_EVALORDERUNCON,
1128 FLG_FUNCUNUSED,
1129 FLG_EXPORTITER, FLG_EXPORTCONST,
1130 FLG_TYPEUNUSED, FLG_FIELDUNUSED, FLG_PARAMUNUSED, FLG_TOPUNUSED,
1131 FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED,
1132 FLG_VARUNUSED,
1133 FLG_NULLPOINTERARITH, FLG_POINTERARITH,
1134 FLG_PTRNUMCOMPARE,
1135 FLG_BOOLCOMPARE, FLG_NOEFFECT,
1136 FLG_RETVALINT, FLG_RETVALBOOL, FLG_RETVALOTHER,
1137 FLG_ANSIRESERVED, FLG_ANSIRESERVEDLOCAL, FLG_CPPNAMES,
1138 FLG_RETVALBOOL, FLG_RETVALINT, FLG_SPECUNDEF,
1139 FLG_DECLUNDEF, FLG_STRICTOPS, FLG_INCONDEFS,
1140 FLG_INCONDEFSLIB, FLG_MATCHFIELDS, FLG_EXPORTMACRO, FLG_EXPORTVAR,
1141 FLG_EXPORTFCN, FLG_EXPORTTYPE, FLG_EXPORTLOCAL, FLG_MACROPARAMS,
1142 FLG_MACROASSIGN,
1143 FLG_SEFPARAMS, FLG_SEFUNSPEC, FLG_MACROSTMT, FLG_MACROPARENS,
1144 FLG_MACROFCNDECL,
1145 FLG_MACROCONSTDECL,
1146 FLG_MACROREDEF, FLG_MACROEMPTY,
1147 FLG_INFLOOPS, FLG_INFLOOPSUNCON,
1148 FLG_UNREACHABLE,
1149 FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE, FLG_USEDEF,
1150 FLG_EVALORDER,
1151 FLG_MODUNCON, FLG_MODUNCONNOMODS, FLG_MODINTERNALSTRICT,
1152 FLG_MODOBSERVERUNCON,
1153
1154 FLG_NESTEDEXTERN,
1155 FLG_FIRSTCASE,
1156
1157 /* memchecks flags */
1158 FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
1159 FLG_NULLPASS, FLG_NULLRET,
1160
1161 FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF,
1162
1163 /* memtrans flags */
1164 FLG_EXPOSETRANS,
1165 FLG_OBSERVERTRANS,
1166 FLG_DEPENDENTTRANS,
1167 FLG_NEWREFTRANS,
1168 FLG_ONLYTRANS,
1169 FLG_OWNEDTRANS,
1170 FLG_FRESHTRANS,
1171 FLG_SHAREDTRANS,
1172 FLG_TEMPTRANS,
1173 FLG_KEPTTRANS,
1174 FLG_REFCOUNTTRANS,
1175 FLG_STATICTRANS,
1176 FLG_UNKNOWNTRANS,
1177 FLG_KEEPTRANS,
1178 FLG_IMMEDIATETRANS,
1179 FLG_STATICINITTRANS,
1180 FLG_UNKNOWNINITTRANS,
1181
1182 FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
1183 FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE,
1184 FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
1185 FLG_MEMIMPLICIT,
1186 FLG_BRANCHSTATE,
1187
1188 FLG_DECLPARAMNAME, FLG_DECLPARAMMATCH,
1189
1190 FLG_SHADOW, FLG_DEPARRAYS,
1191 FLG_STRICTDESTROY, FLG_STRICTUSERELEASED, FLG_STRICTBRANCHSTATE,
1192 FLG_REDECL, FLG_READONLYSTRINGS, FLG_READONLYTRANS,
1193 FLG_LOOPLOOPBREAK, FLG_LOOPSWITCHBREAK, FLG_SWITCHLOOPBREAK,
1194 FLG_SWITCHSWITCHBREAK, FLG_LOOPLOOPCONTINUE,
1195 FLG_CHECKSTRICTGLOBALS, FLG_IMPCHECKEDSPECGLOBALS,
1196 FLG_ALLGLOBALS, FLG_IMPCHECKEDSTRICTGLOBALS,
1197 FLG_IMPCHECKEDSTRICTSTATICS,
1198 FLG_IMPCHECKEDSTRICTSPECGLOBALS,
1199 FLG_IMPCHECKMODINTERNALS,
1200 FLG_WARNMISSINGGLOBALS, FLG_WARNMISSINGGLOBALSNOGLOBS,
1201 FLG_WARNLINTCOMMENTS, FLG_ANSIRESERVEDLOCAL,
1202 FLG_INCLUDENEST, FLG_STRINGLITERALLEN,
1203 FLG_NUMSTRUCTFIELDS, FLG_NUMENUMMEMBERS,
1204 FLG_CONTROLNESTDEPTH,
1205 FLG_FORBLOCK, FLG_WHILEBLOCK,
1206 FLG_FOREMPTY, FLG_WHILEEMPTY,
1207 FLG_IFEMPTY, FLG_IFBLOCK,
1208 FLG_ELSEIFCOMPLETE,
1209 FLG_REALCOMPARE, FLG_BOOLOPS,
1210 FLG_SYSTEMDIRERRORS, FLG_UNUSEDSPECIAL,
1211
1212 FLG_SHIFTSIGNED, FLG_BITWISEOPS,
1213 INVALID_FLAG } ;
1214
1215 SETFLAGS ();
1216 }
1217 else
1218 {
1219 llcontbug (message ("context_setMode: bad mode: %s", s));
1220 }
1221}
1222
1223bool
1224context_isSpecialFile (cstring fname)
1225{
1226 char *ext = filenameExtension (cstring_toCharsSafe (fname));
1227
1228 return (mstring_equal (ext, ".y")
1229 || mstring_equal (ext, ".l")
1230 || cstring_equalLit (fname, "lex.yy.c"));
1231}
1232
1233bool
1234context_isSystemDir (cstring dir)
1235{
1236 cstring sysDirs = context_exposeString (FLG_SYSTEMDIRS);
1237 char *thisdir = cstring_toCharsSafe (sysDirs);
1238 char *nextdir = strchr (thisdir, SEPCHAR);
1239
1240 if (nextdir != NULL)
1241 {
1242 *nextdir = '\0';
1243 nextdir += 1;
1244 }
1245
1246 while (thisdir != NULL)
1247 {
1248 DPRINTF (("Test: %s / %s", dir, thisdir));
1249
1250 if (cstring_equalCanonicalPrefix (dir, thisdir))
1251 {
1252 if (nextdir != NULL)
1253 {
1254 *(nextdir - 1) = SEPCHAR;
1255 }
1256
1257 return TRUE;
1258 }
1259
1260 if (nextdir != NULL)
1261 {
1262 *(nextdir - 1) = SEPCHAR;
1263 }
1264
1265 if (nextdir != NULL)
1266 {
1267 thisdir = nextdir;
1268 nextdir = strchr (thisdir, SEPCHAR);
1269
1270 if (nextdir != NULL)
1271 {
1272 *nextdir = '\0';
1273 nextdir += 1;
1274 }
1275 }
1276 else
1277 {
1278 break;
1279 }
1280 }
1281
1282 DPRINTF (("Returns FALSE"));
1283 return FALSE;
1284}
1285
1286void
1287context_addFileAccessType (typeId t)
1288{
1289 cstring base;
1290
1291 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
1292 || gc.kind == CX_UNKNOWNMACRO)
1293 {
1294 gc.acct = typeIdSet_insert (gc.acct, t);
1295 }
1296
1297 gc.facct = typeIdSet_insert (gc.facct, t);
1298
1299 base = fileloc_getBase (g_currentloc);
1300 insertModuleAccess (base, t);
1301 DPRINTF (("Add file access: %s / %s", typeIdSet_unparse (gc.facct),
1302 typeIdSet_unparse (gc.acct)));
1303}
1304
1305void
1306context_removeFileAccessType (typeId t)
1307{
1308 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
1309 || gc.kind == CX_UNKNOWNMACRO)
1310 {
1311 gc.acct = typeIdSet_removeFresh (gc.acct, t);
1312 }
1313
1314 gc.facct = typeIdSet_removeFresh (gc.facct, t);
1315 gc.nacct = typeIdSet_insert (gc.nacct, t);
1316}
1317
1318void context_enterFunctionDecl (void)
1319{
1320 llassert (gc.kind == CX_GLOBAL);
1321 gc.kind = CX_FCNDECL;
1322}
1323
1324void context_exitFunctionDecl (void)
1325{
1326 gc.kind = CX_GLOBAL;
1327}
1328
1329bool context_inFunctionDecl (void)
1330{
1331 return (gc.kind == CX_FCNDECL);
1332}
1333
1334void
1335context_enterMacro (/*@observer@*/ uentry e)
1336{
1337 context_enterFunction (e);
1338 gc.kind = CX_MACROFCN;
1339}
1340
1341void
1342context_enterUnknownMacro (/*@dependent@*/ uentry e)
1343{
1344 llassert (uentry_isFunction (e));
1345 context_enterFunction (e);
1346 gc.kind = CX_UNKNOWNMACRO;
1347}
1348
1349void context_enterAndClause (exprNode e)
1350{
1351
1352 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
1353 pushClause (ANDCLAUSE);
1354}
1355
1356void context_enterOrClause (exprNode e)
1357{
1358 usymtab_trueBranch (guardSet_invert (exprNode_getGuards (e)));
1359 pushClause (ORCLAUSE);
1360}
1361
1362bool context_inDeepLoop (void)
1363{
1364 bool inLoop = FALSE;
1365
1366 clauseStack_elements (gc.clauses, el)
1367 {
1368 if (clause_isLoop (el))
1369 {
1370 if (inLoop)
1371 {
1372 return TRUE;
1373 }
1374
1375 inLoop = TRUE;
1376 }
1377 } end_clauseStack_elements;
1378
1379 return FALSE;
1380}
1381
1382bool context_inDeepSwitch (void)
1383{
1384 bool inLoop = FALSE;
1385
1386 clauseStack_elements (gc.clauses, el)
1387 {
1388 if (clause_isSwitch (el))
1389 {
1390 if (inLoop)
1391 {
1392 return TRUE;
1393 }
1394
1395 inLoop = TRUE;
1396 }
1397 } end_clauseStack_elements;
1398
1399 return FALSE;
1400}
1401
1402bool context_inDeepLoopSwitch (void)
1403{
1404 bool inLoop = FALSE;
1405
1406 clauseStack_elements (gc.clauses, el)
1407 {
1408 if (clause_isBreakable (el))
1409 {
1410 if (inLoop)
1411 {
1412 return TRUE;
1413 }
1414
1415 inLoop = TRUE;
1416 }
1417 } end_clauseStack_elements;
1418
1419 return FALSE;
1420}
1421
1422clause context_breakClause (void)
1423{
1424 clauseStack_elements (gc.clauses, el)
1425 {
1426 if (clause_isSwitch (el))
1427 {
1428 return el;
1429 }
1430 else if (clause_isLoop (el))
1431 {
1432 return el;
1433 }
1434 else
1435 {
1436 ;
1437 }
1438 } end_clauseStack_elements;
1439
1440 return NOCLAUSE;
1441}
1442
1443clause context_nextBreakClause (void)
1444{
1445 bool hasOne = FALSE;
1446
1447 clauseStack_elements (gc.clauses, el)
1448 {
1449 if (clause_isBreakable (el))
1450 {
1451 if (hasOne)
1452 {
1453 return el;
1454 }
1455 else
1456 {
1457 hasOne = TRUE;
1458 }
1459 }
1460 } end_clauseStack_elements;
1461
1462 return NOCLAUSE;
1463}
1464
1465bool context_inConditional (void)
1466{
1467 clauseStack_elements (gc.clauses, el)
1468 {
1469 /*
1470 ** Should also include TRUECLAUSE and FALSECLAUSE, but need
1471 ** to distinguish if from ? for this
1472 */
1473
1474 if (clause_isBreakable (el) && (el != DOWHILECLAUSE))
1475 {
1476 return TRUE;
1477 }
1478 } end_clauseStack_elements;
1479
1480 return FALSE;
1481}
1482
1483void context_exitAndClause (exprNode pred, exprNode tbranch)
1484{
1485 context_setJustPopped ();
1486
1487 llassert (gc.inclause == ANDCLAUSE);
1488
1489 usymtab_popAndBranch (pred, tbranch);
1490 clauseStack_pop (gc.clauses);
1491 gc.inclause = topClause (gc.clauses);
1492}
1493
1494void context_exitOrClause (exprNode pred, exprNode tbranch)
1495{
1496 context_setJustPopped ();
1497
1498 llassert (gc.inclause == ORCLAUSE);
1499
1500 usymtab_popOrBranch (pred, tbranch);
1501 clauseStack_pop (gc.clauses);
1502 gc.inclause = topClause (gc.clauses);
1503}
1504
1505static void context_enterCondClauseAux (clause cl)
1506 /*@modifies gc@*/
1507{
1508 pushClause (cl);
1509}
1510
1511static void context_enterTrueAux (exprNode e, clause cl)
1512 /*@modifies gc@*/
1513{
1514 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
1515 pushClause (cl);
1516}
1517
1518void context_enterIterClause (void)
1519{
1520 context_enterTrueAux (exprNode_undefined, ITERCLAUSE);
1521}
1522
1523void context_enterDoWhileClause (void)
1524{
1525 pushClause (DOWHILECLAUSE);
1526}
1527
1528void context_enterWhileClause (exprNode e)
1529{
1530 context_enterTrueAux (e, WHILECLAUSE);
1531}
1532
1533void context_enterForClause (exprNode e)
1534{
1535 context_enterTrueAux (e, FORCLAUSE);
1536}
1537
1538void context_enterTrueClause (exprNode e)
1539{
1540 context_enterTrueAux (e, TRUECLAUSE);
1541}
1542
1543void context_enterSwitch (exprNode e)
1544{
1545
1546 usymtab_switchBranch (e);
1547 context_enterCondClauseAux (SWITCHCLAUSE);
1548}
1549
1550void context_exitSwitch (exprNode e, bool allpaths)
1551{
1552 usymtab_exitSwitch (e, allpaths);
1553
1554 while (clause_isCase (clauseStack_top (gc.clauses)))
1555 {
1556 clauseStack_pop (gc.clauses);
1557 }
1558
1559 context_exitClauseSimp ();
1560}
1561
1562void context_enterCaseClause (exprNode e)
1563{
1564 bool branch = FALSE;
1565
1566 DPRINTF (("Enter case clause!"));
1567
1568 branch = usymtab_newCase (exprNode_undefined, e);
1569
1570 if (branch)
1571 {
1572 context_enterCondClauseAux (CASECLAUSE);
1573 }
1574}
1575
1576static void context_enterFalseClauseAux (exprNode e, clause cl)
1577 /*@modifies gc@*/
1578{
1579 usymtab_altBranch (guardSet_invert (exprNode_getGuards (e)));
1580 gc.inclause = cl;
1581 clauseStack_switchTop (gc.clauses, cl);
1582}
1583
1584void context_enterFalseClause (exprNode e)
1585{
1586
1587 context_enterFalseClauseAux (e, FALSECLAUSE);
1588}
1589
1590void
1591context_enterConstantMacro (/*@exposed@*/ /*@dependent@*/ uentry e)
1592{
1593 gc.kind = CX_MACROCONST;
1594 gc.cont.fcn = e;
1595 gc.showfunction = context_getFlag (FLG_SHOWFUNC);
1596
1597 gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)),
1598 gc.nacct);
1599
1600
1601 usymtab_enterScope ();
1602 sRef_enterFunctionScope ();
1603
1604 gc.globs = globSet_undefined;
1605 globSet_clear (gc.globs_used);
1606 gc.mods = sRefSet_undefined;
1607}
1608
1609uentry context_getHeader (void)
1610{
1611 if (!(context_inFunctionLike () || (gc.kind == CX_MACROCONST)))
1612 {
1613 llfatalbug (message ("context_getHeader: bad call: %q",
1614 context_unparse ()));
1615 }
1616
1617 return (gc.cont.fcn);
1618}
1619
1620void
1621context_setFunctionDefined (fileloc loc)
1622{
1623 switch (gc.kind)
1624 {
1625 case CX_UNKNOWNMACRO:
1626 case CX_FUNCTION:
1627 case CX_MACROFCN:
1628 uentry_setFunctionDefined (gc.cont.fcn, loc);
1629 break;
1630 default:
1631 /* (not a bug because of parse errors) */
1632 break;
1633 }
1634}
1635
1636void
1637context_enterFunction (/*@exposed@*/ uentry e)
1638{
1639 gc.kind = CX_FUNCTION;
1640 gc.cont.fcn = e;
1641
1642 if (uentry_hasAccessType (e))
1643 {
1644 gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)),
1645 gc.nacct);
1646 }
1647 else
1648 {
1649 gc.acct = gc.facct;
1650 }
1651
1652 DPRINTF (("Enter function: %s / %s", uentry_unparse (e),
1653 typeIdSet_unparse (gc.acct)));
1654
1655 gc.showfunction = context_getFlag (FLG_SHOWFUNC);
1656
1657 gc.globs = uentry_getGlobs (e);
1658 globSet_clear (gc.globs_used);
1659 gc.mods = uentry_getMods (e);
1660
1661 usymtab_enterFunctionScope (e);
1662 sRef_enterFunctionScope ();
1663}
1664
1665static bool context_checkStrictGlobals (void)
1666{
1667 return (context_getFlag (FLG_CHECKSTRICTGLOBALS));
1668}
1669
1670static bool context_hasGlobs (void)
1671{
1672 if (context_inFunctionLike ())
1673 {
1674 return (uentry_hasGlobs (gc.cont.fcn));
1675 }
1676 else
1677 {
1678 return (FALSE);
1679 }
1680}
1681
1682static bool context_checkCheckedGlobals (void)
1683{
1684 return (context_getFlag (FLG_GLOBALS)
1685 && (context_getFlag (FLG_GLOBUNSPEC)
1686 || context_hasGlobs ()));
1687}
1688
1689static bool context_checkUnknownGlobals (void)
1690{
1691 /* should be uentry_hasGlobs ? */
1692
1693 return (context_getFlag (FLG_ALLGLOBALS)
1694 && (context_getFlag (FLG_GLOBUNSPEC)
1695 || context_hasGlobs ()));
1696}
1697
1698static bool context_checkUncheckedGlobals (void)
1699{
1700 return (FALSE);
1701}
1702
1703bool
1704context_checkExport (uentry e)
1705{
1706 if (!gc.anyExports) return FALSE;
1707
1708 if (uentry_isFunction (e)
1709 || (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))))
1710 {
1711 return context_maybeSet (FLG_EXPORTFCN);
1712 }
1713 else if (uentry_isExpandedMacro (e))
1714 {
1715 return context_maybeSet (FLG_EXPORTMACRO);
1716 }
1717 else if (uentry_isVariable (e))
1718 {
1719 return context_maybeSet (FLG_EXPORTVAR);
1720 }
1721 else if (uentry_isEitherConstant (e))
1722 {
1723 return context_maybeSet (FLG_EXPORTCONST);
1724 }
1725 else if (uentry_isIter (e) || uentry_isEndIter (e))
1726 {
1727 return context_maybeSet (FLG_EXPORTITER);
1728 }
1729 else if (uentry_isDatatype (e))
1730 {
1731 return context_maybeSet (FLG_EXPORTTYPE);
1732 }
1733 else
1734 {
1735 BADEXIT;
1736 }
1737}
1738
1739bool
1740context_checkGlobUse (uentry glob)
1741{
1742
1743 if (uentry_isCheckedStrict (glob))
1744 {
1745 return context_checkStrictGlobals ();
1746 }
1747 else if (uentry_isChecked (glob))
1748 {
1749 return context_checkCheckedGlobals ();
1750 }
1751 else if (uentry_isCheckedUnknown (glob) || uentry_isCheckMod (glob))
1752 {
1753 return context_checkUnknownGlobals ();
1754 }
1755 else
1756 {
1757 llassert (uentry_isUnchecked (glob));
1758
1759 return context_checkUncheckedGlobals ();
1760 }
1761}
1762
1763bool
1764context_checkAliasGlob (uentry glob)
1765{
1766 if (uentry_isCheckedStrict (glob))
1767 {
1768 return gc.flags[FLG_CHECKSTRICTGLOBALIAS];
1769 }
1770 else if (uentry_isChecked (glob))
1771 {
1772 return gc.flags[FLG_CHECKEDGLOBALIAS];
1773 }
1774 else if (uentry_isCheckMod (glob))
1775 {
1776 return gc.flags[FLG_CHECKMODGLOBALIAS];
1777 }
1778 else
1779 {
1780 llassert (uentry_isUnchecked (glob) || uentry_isCheckedUnknown (glob));
1781
1782 return gc.flags[FLG_UNCHECKEDGLOBALIAS];
1783 }
1784}
1785
1786bool context_checkInternalUse (void)
1787{
1788 if (context_hasGlobs ())
1789 {
1790 return (gc.flags[FLG_INTERNALGLOBS]);
1791 }
1792 else
1793 {
1794 return (gc.flags[FLG_INTERNALGLOBSNOGLOBS]);
1795 }
1796}
1797
1798bool
1799context_checkGlobMod (sRef el)
1800{
1801 uentry ue = sRef_getUentry (el);
1802
1803 /* no: llassert (sRef_isGlobal (el)); also check local statics */
1804
1805 if (uentry_isCheckedModify (ue)
1806 || (!uentry_isUnchecked (ue) && (gc.flags[FLG_ALLGLOBALS])))
1807 {
1808 if (context_hasMods ())
1809 {
1810 return (gc.flags[FLG_MODGLOBS]);
1811 }
1812 else
1813 {
1814 if (uentry_isCheckedStrict (ue))
1815 {
1816 return (gc.flags[FLG_MODGLOBSUNSPEC]);
1817 }
1818 else
1819 {
1820 return (gc.flags[FLG_MODSTRICTGLOBSUNSPEC]);
1821 }
1822 }
1823 }
1824 else
1825 {
1826 if (context_hasMods ())
1827 {
1828 return (gc.flags[FLG_MODGLOBSUNCHECKED]);
1829 }
1830 else
1831 {
1832 return FALSE;
1833 }
1834 }
1835}
1836
1837void
1838context_usedGlobal (sRef el)
1839{
1840 if (!globSet_member (gc.globs_used, el))
1841 {
1842 /*
1843 ** The first time a global is used in a function, we need
1844 ** to clear the derived sRefs, since they were set for the
1845 ** previous function.
1846 */
1847
1848 sRef_clearDerived (el);
1849 gc.globs_used = globSet_insert (gc.globs_used, el);
1850 }
1851}
1852
1853/*@observer@*/ sRefSet
1854context_modList (void)
1855{
1856 return gc.mods;
1857}
1858
1859bool
1860context_globAccess (sRef s)
1861{
1862 llassert (sRef_isGlobal (s) || sRef_isKindSpecial (s));
1863 return (globSet_member (gc.globs, s));
1864}
1865
1866bool
1867context_hasAccess (typeId t)
1868{
1869 if (context_inFunctionLike ())
1870 {
1871 return (typeIdSet_member (gc.acct, t));
1872 }
1873 else
1874 {
1875 return (context_hasFileAccess (t));
1876 }
1877}
1878
1879bool
1880context_hasFileAccess (typeId t)
1881{
1882 return (typeIdSet_member (gc.facct, t));
1883}
1884
1885/*@only@*/ cstring
1886context_unparseAccess (void)
1887{
1888 return (message ("%q / %q", typeIdSet_unparse (gc.acct),
1889 typeIdSet_unparse (gc.facct)));
1890}
1891
1892/*@only@*/ cstring
1893context_unparseClauses (void)
1894{
1895 return (clauseStack_unparse (gc.clauses));
1896}
1897
1898bool
1899context_couldHaveAccess (typeId t)
1900{
1901 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN || gc.kind == CX_UNKNOWNMACRO)
1902 {
1903 return (typeIdSet_member (gc.acct, t));
1904 }
1905 else
1906 {
1907 return (typeIdSet_member (gc.facct, t));
1908 }
1909}
1910
1911ctype
1912context_getRetType (void)
1913{
1914 ctype f = ctype_undefined;
1915
1916 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN)
1917 {
1918 f = uentry_getType (gc.cont.fcn);
1919 }
1920 else if (gc.kind == CX_UNKNOWNMACRO)
1921 {
1922 return ctype_unknown;
1923 }
1924 else
1925 {
1926 llcontbuglit ("context_getRetType: not in a function context");
1927 return ctype_unknown;
1928 }
1929
1930 if (!ctype_isFunction (f))
1931 {
1932 if (ctype_isKnown (f))
1933 {
1934 llbuglit ("context_getRetType: not a function");
1935 }
1936
1937 return ctype_unknown;
1938 }
1939 return (ctype_returnValue (f));
1940}
1941
1942bool
1943context_hasMods (void)
1944{
1945 if (context_inFunctionLike ())
1946 {
1947 return (uentry_hasMods (gc.cont.fcn));
1948 }
1949 else
1950 {
1951 return FALSE;
1952 }
1953}
1954
1955void
1956context_exitAllClauses (void)
1957{
1958
1959 while (!clauseStack_isEmpty (gc.clauses))
1960 {
1961 clause el = clauseStack_top (gc.clauses);
1962
1963 gc.inclause = el;
1964
1965 if (clause_isNone (el))
1966 {
1967 usymtab_quietExitScope (g_currentloc);
1968 clauseStack_pop (gc.clauses);
1969 }
1970 else
1971 {
1972 context_exitClausePlain ();
1973 }
1974 }
1975
1976 clauseStack_clear (gc.clauses);
1977
1978
1979 gc.inclause = NOCLAUSE;
1980}
1981
1982static
1983void context_exitClauseSimp (void)
1984{
1985
1986 context_setJustPopped ();
1987 clauseStack_pop (gc.clauses);
1988 gc.inclause = topClause (gc.clauses);
1989}
1990
1991static
1992void context_exitCaseClause (void)
1993{
1994 context_setJustPopped ();
1995 usymtab_popCaseBranch ();
1996 clauseStack_pop (gc.clauses);
1997 gc.inclause = topClause (gc.clauses);
1998}
1999
2000static
2001void context_exitClauseAux (exprNode pred, exprNode tbranch)
2002{
2003 context_setJustPopped ();
2004 usymtab_popTrueBranch (pred, tbranch, gc.inclause);
2005 clauseStack_pop (gc.clauses);
2006 gc.inclause = topClause (gc.clauses);
2007}
2008
2009void context_exitTrueClause (exprNode pred, exprNode tbranch)
2010{
2011 if (gc.inclause != TRUECLAUSE)
2012 {
2013 llparseerror (cstring_makeLiteral
2014 ("Likely parse error. Conditional clauses are inconsistent."));
2015 return;
2016 }
2017
2018
2019 context_setJustPopped ();
2020
2021 usymtab_popTrueBranch (pred, tbranch, TRUECLAUSE);
2022 clauseStack_pop (gc.clauses);
2023 gc.inclause = topClause (gc.clauses);
2024
2025 }
2026
2027void context_exitIterClause (exprNode body)
2028{
2029 llassert (gc.inclause == ITERCLAUSE);
2030
2031 context_setJustPopped ();
2032
2033 if (context_getFlag (FLG_LOOPEXEC))
2034 {
2035 usymtab_popTrueExecBranch (exprNode_undefined, body, ITERCLAUSE);
2036 }
2037 else
2038 {
2039 usymtab_popTrueBranch (exprNode_undefined, body, ITERCLAUSE);
2040 }
2041
2042 clauseStack_pop (gc.clauses);
2043 gc.inclause = topClause (gc.clauses);
2044}
2045
2046static void context_popCase (void) {
2047 /*
2048 ** If we are exiting an outer clause, sometimes still in a switch case.
2049 **
2050 ** e.g.:
2051 **
2052 ** switch(a)
2053 ** {
2054 ** case 1:
2055 ** while (c>3)
2056 ** {
2057 ** case 3: ++c;
2058 ** }
2059 ** }
2060 */
2061
2062 DPRINTF (("Popping case clause: %s",
2063 clauseStack_unparse (gc.clauses)));
2064
2065 if (gc.inclause == CASECLAUSE) {
2066 context_exitCaseClause ();
2067 }
2068}
2069
2070void context_exitWhileClause (exprNode pred, exprNode body)
2071{
2072 guardSet invGuards = guardSet_invert (exprNode_getGuards (pred));
2073
2074 context_popCase ();
2075
2076 if (gc.inclause != WHILECLAUSE) {
2077 DPRINTF (("Clause: %s / %s", clause_unparse (gc.inclause),
2078 clauseStack_unparse (gc.clauses)));
2079 }
2080
2081 llassert (gc.inclause == WHILECLAUSE);
2082
2083 context_setJustPopped ();
2084
2085
2086 /*
2087 ** predicate must be false after while loop (unless there are breaks)
2088 */
2089
2090 if (context_getFlag (FLG_LOOPEXEC))
2091 {
2092 usymtab_popTrueExecBranch (pred, body, WHILECLAUSE);
2093 }
2094 else
2095 {
2096 usymtab_popTrueBranch (pred, body, WHILECLAUSE);
2097 }
2098
2099
2100 usymtab_addGuards (invGuards);
2101 guardSet_free (invGuards);
2102
2103 clauseStack_pop (gc.clauses);
2104 gc.inclause = topClause (gc.clauses);
2105}
2106
2107void context_exitDoWhileClause (exprNode pred)
2108{
2109 guardSet invGuards = guardSet_invert (exprNode_getGuards (pred));
2110
2111 if (gc.inclause == CASECLAUSE) {
2112 /* handle Duff's device */
2113 clauseStack_pop (gc.clauses);
2114 gc.inclause = topClause (gc.clauses);
2115 }
2116
2117 llassert (gc.inclause == DOWHILECLAUSE);
2118
2119 context_setJustPopped ();
2120
2121
2122 usymtab_addGuards (invGuards);
2123 guardSet_free (invGuards);
2124
2125 clauseStack_pop (gc.clauses);
2126 gc.inclause = topClause (gc.clauses);
2127}
2128
2129void context_exitForClause (exprNode forPred, exprNode body)
2130{
2131 guardSet invGuards = guardSet_invert (exprNode_getForGuards (forPred));
2132
2133 llassert (gc.inclause == FORCLAUSE);
2134 context_setJustPopped ();
2135
2136 /*
2137 ** predicate must be false after while loop (unless there are breaks)
2138 */
2139
2140 if (context_getFlag (FLG_LOOPEXEC))
2141 {
2142 usymtab_popTrueExecBranch (forPred, body, FORCLAUSE);
2143 }
2144 else
2145 {
2146 usymtab_popTrueBranch (forPred, body, FORCLAUSE);
2147 }
2148
2149 usymtab_addGuards (invGuards);
2150 guardSet_free (invGuards);
2151 clauseStack_pop (gc.clauses);
2152 gc.inclause = topClause (gc.clauses);
2153}
2154
2155static void context_exitClausePlain (void)
2156{
2157 llassert (gc.inclause != NOCLAUSE);
2158
2159 if (gc.inclause == FALSECLAUSE)
2160 {
2161 context_exitClause (exprNode_undefined, exprNode_undefined, exprNode_undefined);
2162 }
2163 else
2164 {
2165 context_exitClauseAux (exprNode_undefined, exprNode_undefined);
2166 }
2167
2168}
2169
2170void context_exitClause (exprNode pred, exprNode tbranch, exprNode fbranch)
2171{
2172
2173 context_setJustPopped ();
2174
2175 if (gc.inclause == FALSECLAUSE)
2176 {
2177 usymtab_popBranches (pred, tbranch, fbranch, FALSE, FALSECLAUSE);
2178
2179 llassert (clauseStack_top (gc.clauses) == FALSECLAUSE);
2180
2181 clauseStack_pop (gc.clauses);
2182 gc.inclause = topClause (gc.clauses);
2183 }
2184 else
2185 {
2186 context_exitTrueClause (pred, tbranch);
2187 }
2188}
2189
2190void
2191context_returnFunction (void)
2192{
2193 usymtab_checkFinalScope (TRUE);
2194}
2195
2196void
2197context_exitFunction (void)
2198{
2199 if (!context_inFunction () && !context_inMacroConstant ()
2200 && !context_inMacroUnknown ()
2201 && !context_inIterDef () && !context_inIterEnd ())
2202 {
2203 /*
2204 ** not a bug because of parse errors
2205 */
2206 }
2207 else
2208 {
2209 if (context_inMacro () && usymtab_inFunctionScope ())
2210 {
2211 usymtab_exitScope (exprNode_undefined);
2212 }
2213
2214 if (uentry_hasGlobs (gc.cont.fcn))
2215 {
2216 exprChecks_checkUsedGlobs (gc.globs, gc.globs_used);
2217 }
2218
2219
2220 if (uentry_hasMods (gc.cont.fcn))
2221 {
2222 if (context_getFlag (FLG_MUSTMOD))
2223 {
2224 exprNode_checkAllMods (gc.mods, gc.cont.fcn);
2225 }
2226 }
2227
2228 /*
2229 ** clear file static modifies
2230 */
2231
2232 /* do this first to get unused error messages */
2233
2234 usymtab_exitScope (exprNode_undefined);
2235 sRef_exitFunctionScope ();
2236
2237 gc.showfunction = FALSE;
2238 gc.kind = CX_GLOBAL;
2239 gc.cont.glob = TRUE;
2240 gc.acct = gc.facct;
2241 gc.globs = globSet_new ();
2242 globSet_clear (gc.globs_used);
2243 gc.mods = sRefSet_new ();
2244 }
2245
2246 llassert (clauseStack_isEmpty (gc.clauses));
2247 llassert (gc.inclause == NOCLAUSE);
2248}
2249
2250void
2251context_quietExitFunction (void)
2252{
2253 while (gc.kind == CX_INNER)
2254 {
2255 context_exitInnerPlain ();
2256 }
2257
2258 if (!context_inFunction () && !context_inMacroConstant () && !context_inMacroUnknown ()
2259 && !context_inIterDef () && !context_inIterEnd ())
2260 {
2261 }
2262 else
2263 {
2264 usymtab_quietExitScope (g_currentloc);
2265
2266 gc.showfunction = FALSE;
2267 gc.kind = CX_GLOBAL;
2268 gc.cont.glob = TRUE;
2269 gc.acct = gc.facct;
2270 gc.globs = globSet_new ();
2271 globSet_clear (gc.globs_used);
2272 gc.mods = sRefSet_new ();
2273
2274 sRef_exitFunctionScope ();
2275 }
2276}
2277
2278/*@observer@*/ uentryList
2279context_getParams (void)
2280{
2281 if (context_inFunctionLike ())
2282 {
2283 return (uentry_getParams (gc.cont.fcn));
2284 }
2285 else
2286 {
2287 llcontbug (message ("context_getParams: not in function: %q", context_unparse ()));
2288 return uentryList_undefined;
2289 }
2290}
2291
2292/*@observer@*/ globSet
2293context_getUsedGlobs (void)
2294{
2295 llassert (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
2296 || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
2297
2298 return (gc.globs_used);
2299}
2300
2301cstring
2302context_moduleName ()
2303{
2304 return (fileloc_getBase (g_currentloc));
2305}
2306
2307/*@observer@*/ globSet
2308context_getGlobs (void)
2309{
2310 llassert (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
2311 || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
2312
2313 return (gc.globs);
2314}
2315
2316void
2317context_addBoolAccess (void)
2318{
2319 cstring bname = context_getString (FLG_BOOLTYPE);
2320 typeIdSet boolt = typeIdSet_single (usymtab_getTypeId (bname));
2321
2322 addModuleAccess (cstring_copy (bname), boolt);
2323
2324 /* for sys/types (perhaps, this is bogus!) */
2325 addModuleAccess (cstring_makeLiteral ("types"), boolt);
2326}
2327
2328# if 0
2329bool
2330context_canAccessBool (void)
2331{
2332 return TRUE;
2333}
2334# endif
2335
2336/*
2337 static typeId boolType = typeId_invalid;
2338
2339 if (typeId_isInvalid (boolType))
2340 {
2341 boolType = usymtab_getTypeId (context_getBoolName ());
2342 }
2343
2344 if (typeId_isInvalid (boolType)) {
2345 return FALSE;
2346 } else {
2347 return (typeIdSet_member (gc.acct, boolType));
2348 }
2349}
2350*/
2351
2352/* evs 2000-07-25: old version - replaced */
2353
2354ctype
2355context_boolImplementationType () {
2356 /* For now, this is bogus! */
2357 return ctype_int;
2358}
2359
2360bool
2361context_canAccessBool (void)
2362{
2363 static typeId boolType = typeId_invalid;
2364
2365 if (typeId_isInvalid (boolType))
2366 {
2367 boolType = usymtab_getTypeId (context_getBoolName ());
2368 }
2369
2370 if (!typeId_isInvalid (boolType))
2371 {
2372 return context_hasAccess (boolType);
2373 }
2374 else
2375 {
2376 ;
2377 }
2378
2379 return FALSE;
2380}
2381
2382void
2383context_setMessageAnnote (/*@only@*/ cstring s)
2384{
2385 llassert (cstring_isUndefined (gc.msgAnnote));
2386 gc.msgAnnote = s;
2387}
2388
2389bool
2390context_hasMessageAnnote (void)
2391{
2392 return (cstring_isDefined (gc.msgAnnote));
2393}
2394
2395void
2396context_clearMessageAnnote (void)
2397{
2398 if (cstring_isDefined (gc.msgAnnote))
2399 {
2400 cstring_free (gc.msgAnnote);
2401 gc.msgAnnote = cstring_undefined;
2402 }
2403}
2404
2405/*@only@*/ cstring
2406context_getMessageAnnote (void)
2407{
2408 cstring st = gc.msgAnnote;
2409
2410 gc.msgAnnote = cstring_undefined;
2411 return st;
2412}
2413
2414void
2415context_setAliasAnnote (/*@observer@*/ sRef s, /*@observer@*/ sRef t)
2416{
2417 llassert (sRef_isInvalid (gc.aliasAnnote));
2418 llassert (!sRef_sameName (s, t));
2419 gc.aliasAnnote = s;
2420 gc.aliasAnnoteAls = t;
2421}
2422
2423bool
2424context_hasAliasAnnote (void)
2425{
2426 return (sRef_isValid (gc.aliasAnnote));
2427}
2428
2429void
2430context_clearAliasAnnote (void)
2431{
2432 gc.aliasAnnote = sRef_undefined;
2433}
2434
2435cstring
2436context_getAliasAnnote (void)
2437{
2438 sRef ret = gc.aliasAnnote;
2439 sRef als = gc.aliasAnnoteAls;
2440
2441 llassert (sRef_isValid (ret) && sRef_isValid (als));
2442
2443 gc.aliasAnnote = sRef_undefined;
2444 return (message ("%q aliases %q", sRef_unparse (als), sRef_unparse (ret)));
2445}
2446
2447void
2448context_recordFileModifies (sRefSet mods)
2449{
2450 gc.modrecs = sRefSetList_add (gc.modrecs, mods);
2451}
2452
2453void
2454context_recordFileGlobals (globSet mods)
2455{
2456 /*@access globSet@*/ context_recordFileModifies (mods); /*@noaccess globSet@*/
2457}
2458
2459void
2460context_setCommentMarkerChar (char c)
2461{
2462 llassert (c != '\0');
2463
2464 context_setValue (FLG_COMMENTCHAR, (int) c);
2465}
2466
2467char
2468context_getCommentMarkerChar (void)
2469{
2470 return ((char) context_getValue (FLG_COMMENTCHAR));
2471}
2472
2473static void
2474context_setValue (flagcode flag, int val)
2475{
2476 int index = flagcode_valueIndex (flag);
2477
2478 llassert (index >= 0 && index <= NUMVALUEFLAGS);
2479
2480 if (val <= 0)
2481 {
2482 switch (flag)
2483 {
2484 case FLG_INCLUDENEST:
2485 case FLG_CONTROLNESTDEPTH:
2486 case FLG_STRINGLITERALLEN:
2487 case FLG_NUMSTRUCTFIELDS:
2488 case FLG_NUMENUMMEMBERS:
2489 case FLG_LINELEN:
2490 {
2491 cstring warn = message ("Value for %s must be a positive "
2492 "number (given %d)",
2493 flagcode_unparse (flag), val);
2494
2495 flagWarning (warn);
2496 cstring_free (warn);
2497 val = MINLINELEN;
2498 }
2499 return;
2500 default:
2501 break;
2502 }
2503 }
2504
2505 if (flag == FLG_LINELEN && val < MINLINELEN)
2506 {
2507 cstring warn = message ("Value for %s must be at least %d (given %d)",
2508 flagcode_unparse (flag),
2509 MINLINELEN, val);
2510 flagWarning (warn);
2511 cstring_free (warn);
2512 val = MINLINELEN;
2513 }
2514
2515 gc.values[index] = val;
2516}
2517
2518void
2519context_setValueAndFlag (flagcode flag, int val)
2520{
2521 gc.flags[flag] = TRUE;
2522 context_setValue (flag, val);
2523}
2524
2525int
2526context_getValue (flagcode flag)
2527{
2528 int index = flagcode_valueIndex (flag);
2529
2530 llassert (index >= 0 && index <= NUMVALUEFLAGS);
2531 return (gc.values[index]);
2532}
2533
2534int
2535context_getCounter (flagcode flag)
2536{
2537 int index = flagcode_valueIndex (flag);
2538
2539 llassert (index >= 0 && index <= NUMVALUEFLAGS);
2540 return (gc.counters[index]);
2541}
2542
2543void
2544context_incCounter (flagcode flag)
2545{
2546 int index = flagcode_valueIndex (flag);
2547
2548 llassert (index >= 0 && index <= NUMVALUEFLAGS);
2549 /* check limit */
2550 gc.counters[index]++;
2551}
2552
2553void
2554context_decCounter (flagcode flag)
2555{
2556 int index = flagcode_valueIndex (flag);
2557
2558 llassert (index >= 0 && index <= NUMVALUEFLAGS);
2559 gc.counters[index]--;
2560}
2561
2562bool context_showFunction (void)
2563{
2564 return (gc.showfunction);
2565}
2566
2567void
2568context_setString (flagcode flag, cstring val)
2569{
2570 int index = flagcode_stringIndex (flag);
2571
2572 llassert (index >= 0 && index <= NUMSTRINGFLAGS);
2573
2574 if (flag == FLG_SYSTEMDIRS)
2575 {
2576 llassert (cstring_isDefined (val));
2577
2578 if (cstring_firstChar (val) == '\"')
2579 {
2580 cstring oval = val;
2581 cstring tval = cstring_copy (cstring_suffix (val, 1));
2582
2583 if (cstring_lastChar (tval) != '\"')
2584 {
2585 int n = cstring_length (tval) - 1;
2586
2587 while (isspace ((int) cstring_getChar (tval, n)))
2588 {
2589 n--;
2590 }
2591
2592 if (cstring_getChar (tval, n) != '\"')
2593 {
2594 cstring msg = message ("Setting -systemdirs to string with unmatching quotes: %s", val);
2595 flagWarning (msg);
2596 cstring_free (msg);
2597 }
2598 else
2599 {
2600 cstring otval = tval;
2601 tval = cstring_prefix (tval, n);
2602 cstring_free (otval);
2603 }
2604 }
2605
2606 val = cstring_copy (cstring_clip (tval, cstring_length (tval) - 1));
2607 DPRINTF (("val = %s", val));
2608 cstring_free (tval);
2609 cstring_free (oval);
2610 }
2611 }
2612
2613 if (flag == FLG_TMPDIR)
2614 {
2615 llassert (cstring_isDefined (val));
2616
2617 if (cstring_length (val) == 0)
2618 {
2619 cstring_free (val);
2620 val = message (".%s", cstring_makeLiteralTemp (CONNECTSTR));
2621 }
2622 else if (cstring_lastChar (val) != CONNECTCHAR)
2623 {
2624 val = cstring_appendChar (val, CONNECTCHAR);
2625 }
2626 else
2627 {
2628 ;
2629 }
2630 }
2631
2632 if (cstring_length (val) >= 1
2633 && cstring_firstChar (val) == '"')
2634 {
2635 cstring s = message
2636 ("setting %s to string beginning with \". You probably "
2637 "don't meant to have the \"'s.",
2638 flagcode_unparse (flag));
2639
2640 flagWarning (s);
2641 cstring_free (s);
2642 }
2643
2644 if (flag == FLG_BOOLTYPE)
2645 {
2646
2647 }
2648
2649 gc.strings[index] = val;
2650}
2651
2652static /*@exposed@*/ cstring
2653context_exposeString (flagcode flag)
2654{
2655 int index = flagcode_stringIndex (flag);
2656
2657 llassert (index >= 0 && index <= NUMSTRINGFLAGS);
2658 return (gc.strings[index]);
2659}
2660
2661cstring
2662context_getString (flagcode flag)
2663{
2664 return (context_exposeString (flag));
2665}
2666
2667void
2668context_resetErrors (void)
2669{
2670 gc.numerrors = 0;
2671}
2672
2673void context_initMod (void)
2674 /*@globals undef gc; @*/
2675{
2676 gc.kind = CX_GLOBAL;
2677 gc.instandardlib = FALSE;
2678 gc.numerrors = 0;
2679 gc.neednl = FALSE;
2680 gc.linesprocessed = 0;
2681 gc.speclinesprocessed = 0;
2682 gc.insuppressregion = FALSE;
2683 gc.macroMissingParams = FALSE;
2684 gc.preprocessing = FALSE;
2685 gc.incommandline = FALSE;
2686 gc.mc = macrocache_create ();
2687 gc.nmods = 0;
2688 gc.maxmods = DEFAULTMAXMODS;
2689 gc.moduleaccess = (maccesst *)
2690 dmalloc (sizeof (*gc.moduleaccess) * (gc.maxmods));
2691
2692 gc.library = FLG_ANSILIB;
2693
2694 gc.locstack = filelocStack_new ();
2695 gc.modrecs = sRefSetList_undefined;
2696 gc.anyExports = FALSE;
2697
2698 gc.ftab = fileTable_create ();
2699 gc.msgLog = messageLog_new ();
2700 gc.inimport = FALSE;
2701 gc.inDerivedFile = FALSE;
2702 gc.inheader = FALSE;
2703 gc.markers = flagMarkerList_new ();
2704 gc.cont.glob = TRUE;
2705 gc.showfunction = FALSE;
2706 gc.msgAnnote = cstring_undefined;
2707 gc.aliasAnnote = sRef_undefined;
2708 gc.aliasAnnoteAls = sRef_undefined;
2709 gc.boolType = ctype_bool;
2710 gc.mods = sRefSet_new ();
2711
2712 gc.saveloc = fileloc_undefined;
2713
2714 gc.inmacrocache = FALSE;
2715 gc.inclause = NOCLAUSE;
2716 gc.clauses = clauseStack_new ();
2717 gc.globs = globSet_new ();
2718 gc.nacct = typeIdSet_emptySet ();
2719 gc.acct = typeIdSet_emptySet ();
2720 gc.facct = typeIdSet_emptySet ();
2721 gc.savedFlags = FALSE;
2722 gc.pushloc = fileloc_undefined;
2723 gc.protectVars = FALSE;
2724 gc.justpopped = FALSE;
2725 gc.isNullGuarded = NO;
2726 gc.globs_used = globSet_undefined;
2727
2728 allFlagCodes (code)
2729 {
2730 gc.setGlobally[code] = FALSE;
2731 gc.setLocally[code] = FALSE;
2732 } end_allFlagCodes ;
2733
2734 usymtab_initMod ();
2735
2736 context_resetAllFlags ();
2737 conext_resetAllCounters ();
2738 context_setMode (DEFAULT_MODE);
2739}
2740
2741ctype
2742context_typeofZero (void)
2743{
2744 ctype ct = ctype_int;
2745
2746 if (context_getFlag (FLG_ZEROPTR))
2747 {
2748 ct = ctype_makeConj (ct, ctype_voidPointer);
2749 }
2750
2751 if (context_getFlag (FLG_ZEROBOOL)) {
2752 ct = ctype_makeConj (ct, ctype_bool);
2753 }
2754
2755 return ct;
2756}
2757
2758ctype
2759context_typeofOne (void)
2760{
2761 ctype ct = ctype_int;
2762
2763 /* 1 is on longer a bool (was before 2.4)
2764 if (!context_getFlag (FLG_ABSTRACTBOOL))
2765 {
2766 ct = ctype_makeConj (ct, ctype_bool);
2767 }
2768 */
2769
2770 return (ct);
2771}
2772
2773/*@only@*/ cstring
2774context_unparse (void)
2775{
2776 cstring s;
2777
2778 switch (gc.kind)
2779 {
2780 case CX_LCL:
2781 s = message ("LCL File: %q", fileloc_unparse (g_currentloc));
2782 break;
2783 case CX_LCLLIB:
2784 s = message ("LCL Lib File: %q", fileloc_unparse (g_currentloc));
2785 break;
2786 case CX_GLOBAL:
2787 s = message ("Global Context:%q", fileloc_unparse (g_currentloc));
2788 break;
2789 case CX_INNER:
2790 s = message ("Inner Context:%q", fileloc_unparse (g_currentloc));
2791 break;
2792 case CX_FUNCTION:
2793 s = message ("Function %q :%q \n\taccess %q\n\tmodifies %q",
2794 uentry_unparse (gc.cont.fcn),
2795 fileloc_unparse (g_currentloc),
2796 typeIdSet_unparse (gc.acct),
2797 sRefSet_unparse (gc.mods));
2798 break;
2799 case CX_MACROFCN:
2800 s = message ("Function Macro %q", uentry_unparse (gc.cont.fcn));
2801 break;
2802 case CX_UNKNOWNMACRO:
2803 s = message ("Forward Specified Macro %q", uentry_unparse (gc.cont.fcn));
2804 break;
2805 case CX_MACROCONST:
2806 s = message ("Constant Macro %q", uentry_unparse (gc.cont.fcn));
2807 break;
2808 case CX_ITERDEF:
2809 s = message ("Iter definition %q", uentry_unparse (gc.cont.fcn));
2810 break;
2811 case CX_ITEREND:
2812 s = message ("Iter end %q", uentry_unparse (gc.cont.fcn));
2813 break;
2814 default:
2815 s = message ("Un-unparseable context: %d", (int) gc.kind);
2816 break;
2817 }
2818
2819 s = message ("%q\naccess: %q", s, context_unparseAccess ());
2820 return (s);
2821}
2822
2823extern ctype
2824context_currentFunctionType (void)
2825{
2826 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN)
2827 {
2828 return (uentry_getType (gc.cont.fcn));
2829 }
2830 else if (gc.kind == CX_INNER)
2831 {
2832 llcontbuglit ("context_currentFunctionType: inner context");
2833 do { context_exitInnerPlain (); } while (gc.kind == CX_INNER);
2834 return (context_currentFunctionType ());
2835 }
2836 else
2837 {
2838 llcontbuglit ("context_currentFunctionType: not in function");
2839 return (ctype_undefined);
2840 }
2841}
2842
2843void
2844context_enterInnerContext (void)
2845{
2846 if (gc.kind == CX_GLOBAL)
2847 {
2848 gc.kind = CX_INNER;
2849 gc.cont.cdepth = 1;
2850 }
2851 else if (gc.kind == CX_INNER)
2852 {
2853 gc.cont.cdepth++;
2854 }
2855 else
2856 {
2857 ;
2858 }
2859
2860
2861 usymtab_enterScope ();
2862 pushClause (NOCLAUSE);
2863}
2864
2865void
2866context_exitInnerPlain (void) /*@modifies gc;@*/
2867{
2868 context_exitInner (exprNode_undefined);
2869}
2870
2871void
2872context_exitInner (exprNode exp)
2873{
2874
2875 llassertprint (gc.inclause == NOCLAUSE || gc.inclause == CASECLAUSE,
2876 ("inclause = %s", clause_nameTaken (gc.inclause)));
2877
2878 clauseStack_removeFirst (gc.clauses, NOCLAUSE);
2879 gc.inclause = topClause (gc.clauses);
2880
2881 if (gc.kind == CX_INNER)
2882 {
2883 if (--gc.cont.cdepth == 0)
2884 {
2885 gc.kind = CX_GLOBAL;
2886 gc.cont.glob = TRUE;
2887 }
2888 }
2889 else
2890 {
2891 if (gc.kind == CX_GLOBAL)
2892 {
2893 llcontbuglit ("Attempt to exit global context");
2894 return;
2895 }
2896 }
2897
2898 usymtab_exitScope (exp);
2899}
2900
2901
2902void
2903context_enterStructInnerContext (void)
2904{
2905 if (gc.kind == CX_GLOBAL)
2906 {
2907 gc.kind = CX_INNER;
2908 gc.cont.cdepth = 1;
2909 }
2910 else if (gc.kind == CX_INNER)
2911 {
2912 gc.cont.cdepth++;
2913 }
2914 else
2915 {
2916 ;
2917 }
2918
2919 usymtab_enterScope ();
2920}
2921
2922void
2923context_exitStructInnerContext (void)
2924{
2925 if (gc.kind == CX_INNER)
2926 {
2927 if (--gc.cont.cdepth == 0)
2928 {
2929 gc.kind = CX_GLOBAL;
2930 gc.cont.glob = TRUE;
2931 }
2932 }
2933 else
2934 {
2935 if (gc.kind == CX_GLOBAL)
2936 {
2937 llcontbuglit ("Attempt to exit global context");
2938 return;
2939 }
2940 }
2941
2942 usymtab_exitScope (exprNode_undefined);
2943}
2944
2945void
2946context_exitInnerSafe (void)
2947{
2948
2949 if (gc.kind == CX_INNER)
2950 {
2951 if (--gc.cont.cdepth == 0)
2952 {
2953 gc.cont.cdepth++;
2954 }
2955 }
2956 else if (gc.kind == CX_GLOBAL)
2957 {
2958 llcontbuglit ("Attempt to exit global context");
2959 return;
2960 }
2961 else
2962 {
2963 if (usymtab_inDeepScope ())
2964 {
2965 usymtab_exitScope (exprNode_undefined);
2966 }
2967 }
2968}
2969
2970static
2971void setModuleAccess (void)
2972{
2973 gc.facct = typeIdSet_emptySet ();
2974
2975 if (fileId_isValid (currentFile ()))
2976 {
2977 cstring baseName = fileloc_getBase (g_currentloc);
2978
2979 if (context_getFlag (FLG_ACCESSFILE))
2980 {
2981 if (usymtab_existsType (baseName))
2982 {
2983 gc.facct = typeIdSet_insert (gc.facct,
2984 usymtab_getTypeId (baseName));
2985 }
2986 else
2987 {
2988 ;
2989 }
2990 }
2991
2992 if (context_getFlag (FLG_ACCESSMODULE))
2993 {
2994 int i;
2995 bool hasaccess = FALSE;
2996
2997 for (i = 0; i < gc.nmods; i++)
2998 {
2999 if (cstring_equal (baseName, gc.moduleaccess[i].file))
3000 {
3001 gc.facct = typeIdSet_union (gc.facct, gc.moduleaccess[i].daccess);
3002
3003 hasaccess = TRUE;
3004 break;
3005 }
3006 }
3007 }
3008
3009 gc.acct = gc.facct;
3010 gc.inheader = fileId_isHeader (currentFile ());
3011 }
3012 else
3013 {
3014 llcontbuglit ("Current file not defined\n");
3015 gc.facct = typeIdSet_emptySet ();
3016 gc.acct = gc.facct;
3017 gc.inheader = FALSE;
3018 }
3019
3020 /* 17 Jan 1995: forgot to clear nacct */
3021
3022 gc.nacct = typeIdSet_emptySet ();
3023}
3024
3025static void
3026context_enterFileAux (void)
3027{
3028 setModuleAccess ();
3029}
3030
3031void
3032context_enterFile (void)
3033{
3034 context_enterFileAux ();
3035 usymtab_enterFile ();
3036}
3037
3038void
3039context_enterMacroFile (void)
3040{
3041 context_enterFileAux ();
3042}
3043
3044bool
3045context_inFunction (void)
3046{
3047 kcontext ck = gc.kind;
3048
3049 return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN) || (ck == CX_INNER));
3050}
3051
3052bool
3053context_inFunctionLike (void)
3054{
3055 return (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
3056 || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
3057}
3058
3059bool
3060context_inRealFunction (void)
3061{
3062 kcontext ck = gc.kind;
3063
3064 return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN));
3065}
3066
3067void
3068context_processAllMacros (void)
3069{
3070 usymtab_enterFile ();
3071
3072 gc.inmacrocache = TRUE;
3073 macrocache_processUndefinedElements (gc.mc);
3074 cleanupMessages ();
3075 usymtab_exitFile ();
3076
3077 gc.inmacrocache = FALSE;
3078 macrocache_finalize ();
3079}
3080
3081/*
3082** this happens once at the end of each C file
3083**
3084** check each Macro that was defined in current file.c or current file.h
3085**
3086*/
3087
3088static void
3089context_processMacros (void)
3090{
3091 if (fileId_isValid (currentFile ()))
3092 {
3093 fileloc lastfl;
3094 cstring cbase = cstring_fromChars
3095 (removePathFree
3096 (removeAnyExtension
3097 (cstring_toCharsSafe (fileName (currentFile ())))));
3098
3099 gc.inmacrocache = TRUE;
3100
3101 DPRINTF (("Processing macros: %s", cbase));
3102 lastfl = macrocache_processFileElements (gc.mc, cbase);
3103 DPRINTF (("Processing macros: %s", fileloc_unparse (lastfl)));
3104
3105 cstring_free (cbase);
3106
3107 if (fileloc_isDefined (lastfl))
3108 {
3109 g_currentloc = fileloc_update (g_currentloc, lastfl);
3110 cleanupMessages ();
3111 }
3112
3113 gc.inmacrocache = FALSE;
3114 }
3115}
3116
3117bool
3118context_processingMacros (void)
3119{
3120 return (gc.inmacrocache);
3121}
3122
3123void
3124context_exitFile (void)
3125{
3126 if (gc.kind != CX_GLOBAL)
3127 {
3128 llfatalerrorLoc
3129 (cstring_makeLiteral ("File ended outside global scope"));
3130 }
3131
3132 if (gc.insuppressregion)
3133 {
3134 /* gack...don't reverse the order of these lines! ;-> */
3135 gc.insuppressregion = FALSE;
3136 llerrorlit (FLG_SYNTAX,
3137 "File ended in ignore errors region, "
3138 "possible missing /*@end*/");
3139 }
3140
3141 /* fix up parse errors */
3142
3143 while (!usymtab_inFileScope ())
3144 {
3145 usymtab_quietExitScope (g_currentloc);
3146 }
3147
3148 /*
3149 ** Clear the file-specific modifies information.
3150 */
3151
3152 sRefSetList_elements (gc.modrecs, mods)
3153 {
3154 sRefSet_clearStatics (mods);
3155 } end_sRefSetList_elements ;
3156
3157 sRefSetList_clear (gc.modrecs);
3158
3159 context_processMacros ();
3160 cleanupMessages ();
3161
3162 usymtab_exitFile ();
3163
3164 gc.inDerivedFile = FALSE;
3165 filelocStack_clear (gc.locstack);
3166
3167 gc.nacct = typeIdSet_emptySet (); /* empty noaccess */
3168
3169 gc.cont.glob = TRUE;
3170
3171 if (gc.savedFlags)
3172 {
3173 context_restoreFlagSettings ();
3174 gc.savedFlags = FALSE;
3175 }
3176}
3177
3178void
3179context_exitMacroCache (void)
3180{
3181 if (gc.kind != CX_GLOBAL)
3182 {
3183 if (context_inMacro ()) /* this is okay, file could end without newline in macro */
3184 {
3185 context_exitFunction ();
3186 }
3187 else
3188 {
3189 llcontbug (message ("context_exitMacroCache: outside global scope: %q",
3190 context_unparse ()));
3191 gc.kind = CX_GLOBAL;
3192 }
3193 }
3194
3195 /*
3196 ** no longer valid here
3197 ** if (gc.insuppressregion)
3198 ** {
3199 ** gc.insuppressregion = FALSE;
3200 ** llerror ("File ended in ignore errors region, possible missing @");
3201 ** }
3202 */
3203
3204 gc.cont.glob = TRUE;
3205}
3206
3207void
3208context_saveLocation (void)
3209{
3210 /* was llassert (fileloc_isUndefined (gc.saveloc)) */
3211 fileloc_free (gc.saveloc);
3212
3213
3214 gc.saveloc = fileloc_copy (g_currentloc);
3215 }
3216
3217fileloc
3218context_getSaveLocation (void)
3219{
3220 fileloc fl = gc.saveloc;
3221
3222 gc.saveloc = fileloc_undefined;
3223 return fl;
3224}
3225
3226/*@observer@*/ cstring
3227context_inFunctionName (void)
3228{
3229 if (gc.kind == CX_FUNCTION
3230 || gc.kind == CX_MACROFCN || gc.kind == CX_UNKNOWNMACRO
3231 || gc.kind == CX_MACROCONST
3232 || gc.kind == CX_ITERDEF || gc.kind == CX_ITEREND)
3233 {
3234 return (uentry_rawName (gc.cont.fcn));
3235 }
3236 else
3237 {
3238 llcontbuglit ("context_inFunctionName: not in function");
3239 return (cstring_undefined);
3240 }
3241}
3242
3243void
3244context_userSetFlag (flagcode f, bool b)
3245{
3246 DPRINTF (("set flag: %s", flagcode_name (f)));
3247
3248 if (f == FLG_NEVERINCLUDE && b)
3249 {
3250 if (gc.flags[FLG_EXPORTHEADER])
3251 {
3252 flagWarning (cstring_makeLiteralTemp
3253 ("setting +neverinclude after +exportheader. "
3254 "Turning off exportheader, since headers are not checked "
3255 "when +neverinclude is used."));
3256
3257 gc.flags[FLG_EXPORTHEADER] = FALSE;
3258 }
3259 }
3260 else
3261 {
3262 if (f == FLG_EXPORTHEADER && b)
3263 {
3264 if (gc.flags[FLG_NEVERINCLUDE])
3265 {
3266 flagWarning (cstring_makeLiteralTemp
3267 ("setting +exportheader after +neverinclude. "
3268 "Not setting exportheader, since headers are not checked "
3269 "when +neverinclude is used."));
3270 gc.flags[FLG_EXPORTHEADER] = FALSE;
3271 return;
3272 }
3273 }
3274 }
3275
3276 if (context_getFlag (FLG_WARNFLAGS) && f != FLG_NOF && f != FLG_OPTF)
3277 {
3278 bool lastsetting = context_getFlag (f);
3279
3280 if (bool_equal (lastsetting, b)
3281 && !flagcode_isSpecialFlag (f)
3282 && !flagcode_isIdemFlag (f)
3283 && !flagcode_hasArgument (f))
3284 {
3285 cstring warn = message ("setting %s%s redundant with current value",
3286 cstring_makeLiteralTemp (b ? "+" : "-"),
3287 flagcode_name (f));
3288 flagWarning (warn);
3289 cstring_free (warn);
3290 }
3291 }
3292
3293 if (flagcode_isLibraryFlag (f))
3294 {
3295 if (gc.library != FLG_ANSILIB
3296 && gc.library != f)
3297 {
3298 cstring warn = message ("selecting library %s after library %s was "
3299 "selected (only one library may be used)",
3300 flagcode_name (f),
3301 flagcode_name (gc.library));
3302 flagWarning (warn);
3303 cstring_free (warn);
3304 }
3305
3306 if (f == FLG_UNIXLIB)
3307 {
3308 if (context_getFlag (FLG_WARNUNIXLIB))
3309 {
3310 flagWarning (cstring_makeLiteralTemp
3311 ("selecting unix library. Unix library is "
3312 "ad hoc addition to POSIX library. Recommend "
3313 "use +posixlib to select POSIX library instead. "
3314 "Use -warnunixlib to suppress this message."));
3315 }
3316 }
3317
3318 gc.library = f;
3319 }
3320
3321 gc.setGlobally[f] = TRUE;
3322 context_setFlag (f, b);
3323}
3324
3325void
3326context_fileSetFlag (flagcode f, ynm set)
3327{
3328 if (!gc.savedFlags)
3329 {
3330 context_saveFlagSettings ();
3331 }
3332
3333 if (ynm_isOff (set))
3334 {
3335 context_setFlagAux (f, FALSE, TRUE, FALSE);
3336 }
3337 else if (ynm_isOn (set))
3338 {
3339 context_setFlagAux (f, TRUE, TRUE, FALSE);
3340 gc.setLocally[f] = TRUE;
3341 }
3342 else
3343 {
3344 context_restoreFlag (f);
3345 }
3346}
3347
3348static void
3349context_restoreFlag (flagcode f)
3350{
3351
3352 if (!gc.savedFlags)
3353 {
3354 voptgenerror
3355 (FLG_SYNTAX,
3356 message ("Attempt to restore flag %s when no file scope flags "
3357 "have been set.",
3358 flagcode_unparse (f)),
3359 g_currentloc);
3360 }
3361 else
3362 {
3363 context_addFlagMarker (f, MAYBE);
3364 context_setFlagAux (f, gc.saveflags[f], FALSE, TRUE);
3365 }
3366
3367 }
3368
90bc41f7 3369/*drl7x fix this static */ void
616915dd 3370context_setFlag (flagcode f, bool b)
3371{
3372 context_setFlagAux (f, b, FALSE, FALSE);
3373}
3374
3375void
3376context_setFlagTemp (flagcode f, bool b)
3377{
3378 DPRINTF (("Set flag temp: %s / %s", flagcode_unparse (f), bool_unparse (b)));
3379 gc.flags[f] = b;
3380}
3381
3382/*@notfunction@*/
3383# define DOSET(ff,b) \
3384 do { if (inFile) { gc.setLocally[ff] = TRUE; \
3385 context_addFlagMarker (ff, ynm_fromBool (b)); } \
3386 DPRINTF (("set flag: %s / %s", flagcode_name (ff), bool_unparse (b))); \
3387 gc.flags[ff] = b; } while (FALSE)
3388
3389static void
3390 context_setFlagAux (flagcode f, bool b, bool
3391 inFile, /*@unused@*/ bool isRestore)
3392{
3393 DPRINTF (("set flag: %s / %s", flagcode_unparse (f), bool_unparse (b)));
3394
3395 if (f == FLG_USESTDERR)
3396 {
3397 if (b) {
3398 g_msgstream = stderr;
3399 } else {
3400 g_msgstream = stdout;
3401 }
3402 }
3403
3404 if (flagcode_isSpecialFlag (f))
3405 {
3406 gc.flags[f] = b;
3407
3408
3409 switch (f)
3410 {
3411 case FLG_ALLEMPTY:
3412 DOSET (FLG_ALLEMPTY, b);
3413 DOSET (FLG_IFEMPTY, b);
3414 DOSET (FLG_WHILEEMPTY, b);
3415 DOSET (FLG_FOREMPTY, b);
3416 break;
3417 case FLG_PREDBOOL:
3418 DOSET (FLG_PREDBOOL, b);
3419 DOSET (FLG_PREDBOOLINT, b);
3420 DOSET (FLG_PREDBOOLPTR, b);
3421 DOSET (FLG_PREDBOOLOTHERS, b);
3422 break;
3423 case FLG_GLOBALIAS:
3424 DOSET (FLG_CHECKSTRICTGLOBALIAS, b);
3425 DOSET (FLG_CHECKEDGLOBALIAS, b);
3426 DOSET (FLG_CHECKMODGLOBALIAS, b);
3427 DOSET (FLG_UNCHECKEDGLOBALIAS, b);
3428 break;
3429 case FLG_ALLBLOCK:
3430 DOSET (FLG_ALLBLOCK, b);
3431 DOSET (FLG_IFBLOCK, b);
3432 DOSET (FLG_WHILEBLOCK, b);
3433 DOSET (FLG_FORBLOCK, b);
3434 break;
3435 case FLG_GRAMMAR:
3436 if (b)
3437 {
3438 yydebug = 1;
3439 }
3440 else
3441 {
3442 yydebug = 0;
3443 }
3444
3445 DOSET (FLG_GRAMMAR, b);
3446 break;
3447 case FLG_CODEIMPONLY:
3448 DOSET (FLG_CODEIMPONLY, b);
3449 DOSET (FLG_GLOBIMPONLY, b);
3450 DOSET (FLG_RETIMPONLY, b);
3451 DOSET (FLG_STRUCTIMPONLY, b);
3452 break;
3453 case FLG_SPECALLIMPONLY:
3454 DOSET (FLG_SPECALLIMPONLY, b);
3455 DOSET (FLG_SPECGLOBIMPONLY, b);
3456 DOSET (FLG_SPECRETIMPONLY, b);
3457 DOSET (FLG_SPECSTRUCTIMPONLY, b);
3458 break;
3459 case FLG_ALLIMPONLY:
3460 DOSET (FLG_ALLIMPONLY, b);
3461 DOSET (FLG_GLOBIMPONLY, b);
3462 DOSET (FLG_RETIMPONLY, b);
3463 DOSET (FLG_STRUCTIMPONLY, b);
3464 DOSET (FLG_SPECGLOBIMPONLY, b);
3465 DOSET (FLG_SPECRETIMPONLY, b);
3466 DOSET (FLG_SPECSTRUCTIMPONLY, b);
3467 break;
3468 case FLG_ANSILIMITS:
3469 DOSET (FLG_ANSILIMITS, b);
3470 DOSET (FLG_CONTROLNESTDEPTH, b);
3471 DOSET (FLG_STRINGLITERALLEN, b);
3472 DOSET (FLG_INCLUDENEST, b);
3473 DOSET (FLG_NUMSTRUCTFIELDS, b);
3474 DOSET (FLG_NUMENUMMEMBERS, b);
3475
3476 if (b)
3477 {
3478 context_setValue (FLG_CONTROLNESTDEPTH, DEFAULT_CONTROLNESTDEPTH);
3479 context_setValue (FLG_STRINGLITERALLEN, DEFAULT_STRINGLITERALLEN);
3480 context_setValue (FLG_INCLUDENEST, DEFAULT_INCLUDENEST);
3481 context_setValue (FLG_NUMSTRUCTFIELDS, DEFAULT_NUMSTRUCTFIELDS);
3482 context_setValue (FLG_NUMENUMMEMBERS, DEFAULT_NUMENUMMEMBERS);
3483 }
3484 break;
3485 case FLG_EXTERNALNAMELEN:
3486 DOSET (FLG_DISTINCTEXTERNALNAMES, TRUE);
3487 DOSET (FLG_EXTERNALNAMELEN, TRUE);
3488 break;
3489 case FLG_INTERNALNAMELEN:
3490 DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
3491 DOSET (FLG_INTERNALNAMELEN, TRUE);
3492 break;
3493 case FLG_EXTERNALNAMECASEINSENSITIVE:
3494 DOSET (FLG_EXTERNALNAMECASEINSENSITIVE, b);
3495
3496 if (b && !gc.flags[FLG_DISTINCTEXTERNALNAMES])
3497 {
3498 DOSET (FLG_DISTINCTEXTERNALNAMES, TRUE);
3499 context_setValue (FLG_EXTERNALNAMELEN, 0);
3500 }
3501 break;
3502 case FLG_INTERNALNAMECASEINSENSITIVE:
3503 DOSET (FLG_INTERNALNAMECASEINSENSITIVE, b);
3504
3505 if (b && !gc.flags[FLG_DISTINCTINTERNALNAMES])
3506 {
3507 DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
3508 context_setValue (FLG_INTERNALNAMELEN, 0);
3509 }
3510 break;
3511 case FLG_INTERNALNAMELOOKALIKE:
3512 DOSET (FLG_INTERNALNAMELOOKALIKE, b);
3513
3514 if (b && !gc.flags[FLG_DISTINCTINTERNALNAMES])
3515 {
3516 DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
3517 context_setValue (FLG_INTERNALNAMELEN, 0);
3518 }
3519 break;
3520 case FLG_MODUNSPEC:
3521 DOSET (FLG_MODNOMODS, b);
3522 DOSET (FLG_MODGLOBSUNSPEC, b);
3523 DOSET (FLG_MODSTRICTGLOBSUNSPEC, b);
3524 break;
3525 case FLG_EXPORTANY:
3526 DOSET (FLG_EXPORTVAR, b);
3527 DOSET (FLG_EXPORTFCN, b);
3528 DOSET (FLG_EXPORTTYPE, b);
3529 DOSET (FLG_EXPORTMACRO, b);
3530 DOSET (FLG_EXPORTCONST, b);
3531 gc.anyExports = TRUE;
3532 break;
3533 case FLG_REPEXPOSE:
3534 DOSET (FLG_RETEXPOSE, b);
3535 DOSET (FLG_ASSIGNEXPOSE, b);
3536 DOSET (FLG_CASTEXPOSE, b);
3537 break;
3538 case FLG_RETVAL:
3539 DOSET (FLG_RETVALBOOL, b);
3540 DOSET (FLG_RETVALINT, b);
3541 DOSET (FLG_RETVALOTHER, b);
3542 break;
3543 case FLG_PARTIAL:
3544 if (b)
3545 {
3546 DOSET (FLG_EXPORTLOCAL, FALSE);
3547 DOSET (FLG_DECLUNDEF, FALSE);
3548 DOSET (FLG_SPECUNDEF, FALSE);
3549 DOSET (FLG_TOPUNUSED, FALSE);
3550 }
3551 break;
3552 case FLG_DEEPBREAK:
3553 DOSET (FLG_LOOPLOOPBREAK, b);
3554 DOSET (FLG_LOOPSWITCHBREAK, b);
3555 DOSET (FLG_SWITCHLOOPBREAK, b);
3556 DOSET (FLG_SWITCHSWITCHBREAK, b);
3557 DOSET (FLG_LOOPLOOPCONTINUE, b);
3558 DOSET (FLG_DEEPBREAK, b);
3559 break;
3560 case FLG_ACCESSALL:
3561 DOSET (FLG_ACCESSMODULE, b);
3562 DOSET (FLG_ACCESSFILE, b);
3563 DOSET (FLG_ACCESSCZECH, b);
3564 break;
3565 case FLG_ALLMACROS:
3566 DOSET (FLG_ALLMACROS, b);
3567 DOSET (FLG_FCNMACROS, b);
3568 DOSET (FLG_CONSTMACROS, b);
3569 break;
3570 case FLG_CZECH:
3571 if (b) { DOSET (FLG_ACCESSCZECH, b); }
3572 DOSET (FLG_CZECHFUNCTIONS, b);
3573 DOSET (FLG_CZECHVARS, b);
3574 DOSET (FLG_CZECHCONSTANTS, b);
3575 DOSET (FLG_CZECHTYPES, b);
3576 break;
3577 case FLG_SLOVAK:
3578 if (b) { DOSET (FLG_ACCESSSLOVAK, b); }
3579 DOSET (FLG_SLOVAKFUNCTIONS, b);
3580 DOSET (FLG_SLOVAKVARS, b);
3581 DOSET (FLG_SLOVAKCONSTANTS, b);
3582 DOSET (FLG_SLOVAKTYPES, b);
3583 break;
3584 case FLG_CZECHOSLOVAK:
3585 if (b) { DOSET (FLG_ACCESSCZECHOSLOVAK, b); }
3586 DOSET (FLG_CZECHOSLOVAKFUNCTIONS, b);
3587 DOSET (FLG_CZECHOSLOVAKVARS, b);
3588 DOSET (FLG_CZECHOSLOVAKCONSTANTS, b);
3589 DOSET (FLG_CZECHOSLOVAKTYPES, b);
3590 break;
3591 case FLG_NULL:
3592 DOSET (FLG_NULLSTATE, b);
3593 DOSET (FLG_NULLDEREF, b);
3594 DOSET (FLG_NULLASSIGN, b);
3595 DOSET (FLG_NULLPASS, b);
3596 DOSET (FLG_NULLRET, b);
3597 break;
3598 case FLG_MEMCHECKS:
3599 DOSET (FLG_NULLSTATE, b);
3600 DOSET (FLG_NULLDEREF, b);
3601 DOSET (FLG_NULLASSIGN, b);
3602 DOSET (FLG_NULLPASS, b);
3603 DOSET (FLG_NULLRET, b);
3604 DOSET (FLG_COMPDEF, b);
3605 DOSET (FLG_COMPMEMPASS, b);
3606 DOSET (FLG_UNIONDEF, b);
3607 DOSET (FLG_MEMTRANS, b);
3608 DOSET (FLG_USERELEASED, b);
3609 DOSET (FLG_ALIASUNIQUE, b);
3610 DOSET (FLG_MAYALIASUNIQUE, b);
3611 DOSET (FLG_MUSTFREE, b);
3612 DOSET (FLG_MUSTDEFINE, b);
3613 DOSET (FLG_GLOBSTATE, b);
3614 DOSET (FLG_COMPDESTROY, b);
3615 DOSET (FLG_MUSTNOTALIAS, b);
3616 DOSET (FLG_MEMIMPLICIT, b);
3617 DOSET (FLG_BRANCHSTATE, b);
3618 /*@fallthrough@*/ /* also sets memtrans flags */
3619 case FLG_MEMTRANS:
3620 DOSET (FLG_MEMTRANS, b);
3621 DOSET (FLG_EXPOSETRANS, b);
3622 DOSET (FLG_OBSERVERTRANS, b);
3623 DOSET (FLG_DEPENDENTTRANS, b);
3624 DOSET (FLG_NEWREFTRANS, b);
3625 DOSET (FLG_ONLYTRANS, b);
3626 DOSET (FLG_OWNEDTRANS, b);
3627 DOSET (FLG_FRESHTRANS, b);
3628 DOSET (FLG_SHAREDTRANS, b);
3629 DOSET (FLG_TEMPTRANS, b);
3630 DOSET (FLG_KEPTTRANS, b);
3631 DOSET (FLG_REFCOUNTTRANS, b);
3632 DOSET (FLG_STATICTRANS, b);
3633 DOSET (FLG_UNKNOWNTRANS, b);
3634 DOSET (FLG_KEEPTRANS, b);
3635 DOSET (FLG_IMMEDIATETRANS, b);
3636 break;
3637
3638 default:
3639 llcontbug (message ("Unhandled special flag: %s",
3640 flagcode_unparse (f)));
3641 break;
3642 }
3643 }
3644 else
3645 {
3646 if (flagcode_isIdemFlag (f))
3647 {
3648 DOSET (f, TRUE);
3649 }
3650 else
3651 {
3652 if (b && !gc.anyExports
3653 && (f == FLG_EXPORTVAR || f == FLG_EXPORTFCN
3654 || f == FLG_EXPORTTYPE || f == FLG_EXPORTMACRO
3655 || f == FLG_EXPORTCONST
3656 || f == FLG_EXPORTANY))
3657 {
3658 gc.anyExports = TRUE;
3659 }
3660
3661 DOSET (f, b);
3662 }
3663 }
3664}
3665
3666bool
3667context_maybeSet (flagcode d)
3668{
3669 return (gc.flags[d] || gc.setLocally[d]);
3670}
3671
3672bool
3673context_getFlag (flagcode d)
3674{
3675 return (gc.flags[d]);
3676}
3677
3678static void context_saveFlagSettings (void)
3679{
3680 gc.savedFlags = TRUE;
3681 llassert (sizeof (gc.saveflags) == sizeof (gc.flags));
3682 memcpy (gc.saveflags, gc.flags, sizeof (gc.flags));
3683}
3684
3685static void context_restoreFlagSettings (void)
3686{
3687 llassert (sizeof (gc.saveflags) == sizeof (gc.flags));
3688 memcpy (gc.flags, gc.saveflags, sizeof (gc.flags));
3689 gc.savedFlags = FALSE;
3690}
3691
3692void context_setFilename (fileId fid, int lineno)
3693 /*@globals fileloc g_currentloc;@*/
3694 /*@modifies g_currentloc@*/
3695{
3696 if (fileId_baseEqual (currentFile (), fid))
3697 {
3698 setLine (lineno);
3699 return;
3700 }
3701 else
3702 {
3703 fileloc_setColumn (g_currentloc, 0);
3704
3705 if (fileloc_isSpecialFile (g_currentloc))
3706 {
3707 gc.inDerivedFile = TRUE;
3708 }
3709
3710 if (filelocStack_popPushFile (gc.locstack, g_currentloc))
3711 {
3712 int maxdepth = context_getValue (FLG_INCLUDENEST);
3713
3714 if (filelocStack_size (gc.locstack) > maxdepth)
3715 {
3716 int depth = filelocStack_includeDepth (gc.locstack);
3717
3718 if (depth > maxdepth)
3719 {
3720 if (optgenerror
3721 (FLG_INCLUDENEST,
3722 message ("Maximum include nesting depth "
3723 "(%d, current depth %d) exceeded",
3724 maxdepth,
3725 depth),
3726 filelocStack_nextTop (gc.locstack)))
3727 {
3728 filelocStack_printIncludes (gc.locstack);
3729 }
3730 }
3731 }
3732 }
3733
3734 g_currentloc = fileloc_create (fid, lineno, 1);
3735 gc.inheader = fileId_isHeader (currentFile ());
3736
3737 context_enterFileAux ();
3738 }
3739}
3740
3741void context_enterIterDef (/*@observer@*/ uentry le)
3742{
3743 context_enterMacro (le);
3744 gc.acct = typeIdSet_subtract (gc.facct, gc.nacct);
3745 gc.kind = CX_ITERDEF;
3746}
3747
3748void context_enterIterEnd (/*@observer@*/ uentry le)
3749{
3750 context_enterMacro (le);
3751 gc.kind = CX_ITEREND;
3752}
3753
3754void
3755context_destroyMod (void)
3756 /*@globals killed gc@*/
3757{
3758 setCodePoint ();
3759 ctype_destroyMod ();
3760 setCodePoint ();
3761 usymtab_free ();
3762 setCodePoint ();
3763 fileTable_free (gc.ftab);
3764 filelocStack_free (gc.locstack);
3765 setCodePoint ();
3766 gc.ftab = fileTable_undefined;
3767
3768 macrocache_free (gc.mc);
3769 sfree (gc.moduleaccess);
3770 setCodePoint ();
3771
3772 fileloc_free (gc.saveloc); gc.saveloc = fileloc_undefined;
3773 fileloc_free (gc.pushloc); gc.pushloc = fileloc_undefined;
3774
3775 setCodePoint ();
3776 sRefSetList_free (gc.modrecs);
3777 setCodePoint ();
3778 flagMarkerList_free (gc.markers);
3779 setCodePoint ();
3780 messageLog_free (gc.msgLog);
3781 setCodePoint ();
3782 clauseStack_free (gc.clauses);
3783 setCodePoint ();
3784
3785 cstring_free (gc.msgAnnote);
3786 globSet_free (gc.globs_used);
3787 }
3788
3789/*
3790** Flag shortcuts.
3791*/
3792
3793bool context_msgBoolInt (void)
3794{
3795 return gc.flags [FLG_BOOLINT];
3796}
3797
3798bool context_msgCharInt (void)
3799{
3800 return gc.flags [FLG_CHARINT];
3801}
3802
3803bool context_msgEnumInt (void)
3804{
3805 return gc.flags [FLG_ENUMINT];
3806}
3807
3808bool context_msgPointerArith (void)
3809{
3810 return gc.flags [FLG_POINTERARITH];
3811}
3812
3813bool context_msgStrictOps (void)
3814{
3815 return gc.flags [FLG_STRICTOPS];
3816}
3817
3818# ifndef NOLCL
3819bool context_msgLh (void)
3820{
3821 return gc.flags [FLG_DOLH];
3822}
3823# endif
3824
3825void context_pushLoc (void)
3826{
3827 fileloc_free (gc.pushloc);
3828 gc.pushloc = gc.saveloc;
3829 gc.saveloc = fileloc_undefined;
3830}
3831
3832void context_popLoc (void)
3833{
3834 gc.saveloc = fileloc_update (gc.saveloc, gc.pushloc);
3835}
3836
3837bool context_inGlobalScope (void)
3838{
3839 return (usymtab_inFileScope() || usymtab_inGlobalScope ());
3840}
3841
3842bool context_inInnerScope (void)
3843{
3844 return (gc.kind == CX_INNER);
3845}
3846
3847void context_setProtectVars (void)
3848{
3849 gc.protectVars = TRUE;
3850}
3851
3852bool context_anyErrors (void)
3853{
3854 return (gc.numerrors > 0);
3855}
3856
3857void context_hasError (void)
3858{
3859 gc.numerrors++;
3860}
3861
3862int context_numErrors (void)
3863{
3864 return gc.numerrors;
3865}
3866
3867bool context_neednl (void)
3868{
3869 return gc.neednl;
3870}
3871
3872void context_setNeednl (void)
3873{
3874 gc.neednl = TRUE;
3875}
3876
3877int context_getExpect (void)
3878{
3879 return (context_getValue (FLG_EXPECT));
3880}
3881
3882# ifndef NOLCL
3883int context_getLCLExpect (void)
3884{
3885 return (context_getValue (FLG_LCLEXPECT));
3886}
3887# endif
3888
3889int context_getLimit (void)
3890{
3891 return (context_getValue (FLG_LIMIT));
3892}
3893
3894bool context_unlimitedMessages (void)
3895{
3896 return (context_getLimit () < 0);
3897}
3898
3899void context_releaseVars (void)
3900{
3901 llassert (gc.protectVars);
3902 gc.protectVars = FALSE;
3903}
3904
3905void context_sizeofReleaseVars (void)
3906{
3907 /* If there is a nested sizeof, this might not hold:
3908 llassert (gc.protectVars);
3909 */
3910
3911 gc.protectVars = FALSE;
3912}
3913
3914bool context_inProtectVars (void)
3915{
3916 return (gc.protectVars);
3917}
3918
3919void context_hideShowscan (void)
3920{
3921 gc.flags[FLG_SHOWSCAN] = FALSE;
3922}
3923
3924void context_unhideShowscan (void)
3925{
3926 gc.flags[FLG_SHOWSCAN] = TRUE;
3927}
3928
3929bool context_inHeader (void)
3930{
3931 return (gc.inheader);
3932}
3933
3934fileTable context_fileTable (void)
3935{
3936 return gc.ftab;
3937}
3938
3939cstring context_tmpdir (void)
3940{
3941 return (context_getString (FLG_TMPDIR));
3942}
3943
3944messageLog context_messageLog (void)
3945{
3946 return gc.msgLog;
3947}
3948
3949bool context_inMacroFunction (void)
3950{
3951 return (gc.kind == CX_MACROFCN);
3952}
3953
3954bool context_inMacroConstant (void)
3955{
3956 return (gc.kind == CX_MACROCONST);
3957}
3958
3959bool context_inMacroUnknown (void)
3960{
3961 return (gc.kind == CX_UNKNOWNMACRO);
3962}
3963
3964void context_setShownFunction (void)
3965{
3966 gc.showfunction = FALSE;
3967}
3968
3969bool context_doDump (void)
3970{
3971 return cstring_isNonEmpty (context_getString (FLG_DUMP));
3972}
3973
3974bool context_doMerge (void)
3975{
3976 return cstring_isNonEmpty (context_getString (FLG_MERGE));
3977}
3978
3979cstring context_getDump (void)
3980{
3981 return context_getString (FLG_DUMP);
3982}
3983
3984cstring context_getMerge (void)
3985{
3986 return context_getString (FLG_MERGE);
3987}
3988
3989# ifndef NOLCL
3990bool context_inLCLLib (void)
3991{
3992 return (gc.kind == CX_LCLLIB);
3993}
3994
3995bool context_inImport (void)
3996{
3997 return (gc.inimport);
3998}
3999
4000void context_enterImport (void)
4001{
4002 gc.inimport = TRUE;
4003}
4004
4005void context_leaveImport (void)
4006{
4007 gc.inimport = FALSE;
4008}
4009# endif
4010
4011bool context_inMacro (void)
4012{
4013 return (gc.kind == CX_MACROFCN || gc.kind == CX_MACROCONST
4014 || gc.kind == CX_UNKNOWNMACRO
4015 || gc.kind == CX_ITERDEF || gc.kind == CX_ITEREND);
4016}
4017
4018bool context_inIterDef (void)
4019{
4020 return (gc.kind == CX_ITERDEF);
4021}
4022
4023bool context_inIterEnd (void)
4024{
4025 return (gc.kind == CX_ITEREND);
4026}
4027
4028int context_getLinesProcessed (void)
4029{
4030 return (gc.linesprocessed);
4031}
4032
4033int context_getSpecLinesProcessed (void)
4034{
4035 return (gc.speclinesprocessed);
4036}
4037
4038# ifndef NOLCL
4039void context_processedSpecLine (void)
4040{
4041 gc.speclinesprocessed++;
4042}
4043
4044void context_resetSpecLines (void)
4045{
4046 gc.speclinesprocessed = 0;
4047}
4048# endif
4049
4050bool context_inGlobalContext (void)
4051{
4052 return (gc.kind == CX_GLOBAL);
4053}
4054
4055void context_setFileId (fileId s)
4056{
4057 g_currentloc = fileloc_updateFileId (g_currentloc, s);
4058}
4059
4060bool context_setBoolName (void)
4061{
4062 return (!cstring_equalLit (context_getString (FLG_BOOLTYPE),
4063 DEFAULT_BOOLTYPE));
4064}
4065
4066cstring context_printBoolName (void)
4067{
4068 if (context_setBoolName ())
4069 {
4070 return context_getBoolName ();
4071 }
4072 else
4073 {
4074 return cstring_makeLiteralTemp ("boolean");
4075 }
4076}
4077
4078cstring context_getBoolName (void)
4079{
4080 return (context_getString (FLG_BOOLTYPE));
4081}
4082
4083cstring context_getFalseName (void)
4084{
4085 return (context_getString (FLG_BOOLFALSE));
4086}
4087
4088cstring context_getTrueName (void)
4089{
4090 return (context_getString (FLG_BOOLTRUE));
4091}
4092
4093cstring context_getLarchPath (void)
4094{
4095 return (context_getString (FLG_LARCHPATH));
4096}
4097
4098cstring context_getLCLImportDir (void)
4099{
4100 return (context_getString (FLG_LCLIMPORTDIR));
4101}
4102
4103static void context_setJustPopped (void)
4104{
4105 gc.justpopped = TRUE;
4106}
4107
4108void context_clearJustPopped (void)
4109{
4110 gc.justpopped = FALSE;
4111}
4112
4113bool context_justPopped (void)
4114{
4115 return (gc.justpopped);
4116}
4117
4118void context_setMacroMissingParams (void)
4119{
4120 gc.macroMissingParams = TRUE;
4121}
4122
4123void context_resetMacroMissingParams (void)
4124{
4125 gc.macroMissingParams = FALSE;
4126}
4127
4128bool context_isMacroMissingParams (void)
4129{
4130 return (gc.macroMissingParams);
4131}
4132
4133void context_showFilelocStack (void)
4134{
4135 filelocStack_printIncludes (gc.locstack);
4136}
4137
4138
4139
4140
4141
4142
4143
This page took 0.644299 seconds and 5 git commands to generate.