]> andersk Git - splint.git/blob - src/context.c
Finshed basic merge. Still trying to get it through the test suit.
[splint.git] / src / context.c
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
51 extern /*@external@*/ int yydebug;
52
53 typedef struct
54
55   cstring file; 
56   typeIdSet daccess ; 
57 } maccesst;
58
59 typedef 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
67 static 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
155 static /*@exposed@*/ cstring context_exposeString (flagcode p_flag) ;
156 static void context_restoreFlagSettings (void) /*@modifies gc@*/ ;
157 static void context_saveFlagSettings (void) /*@modifies gc@*/ ;
158 static void context_exitClauseAux (exprNode p_pred, exprNode p_tbranch)
159    /*@modifies gc@*/ ;
160 static void context_exitClauseSimp (void)  /*@modifies gc@*/ ;
161 static void context_exitClausePlain (void) /*@modifies gc@*/ ;
162 static void context_setJustPopped (void) /*@modifies gc.justpopped@*/ ;
163 static void context_setValue (flagcode p_flag, int p_val) /*@modifies gc.flags@*/ ;
164 static void context_setFlag (flagcode p_f, bool p_b)
165   /*@modifies gc.flags@*/ ;
166
167 static void
168   context_setFlagAux (flagcode p_f, bool p_b, bool p_inFile, bool p_isRestore)
169   /*@modifies gc.flags@*/ ;
170
171 static void context_restoreFlag (flagcode p_f) /*@modifies gc.flags@*/ ;
172
173 /*@+enumindex@*/ 
174
175 cstring context_unparseFlagMarkers ()
176 {
177   return (flagMarkerList_unparse (gc.markers));
178 }
179
180 void context_setPreprocessing (void)
181 {
182   llassert (!gc.preprocessing);
183   gc.preprocessing = TRUE;
184 }
185
186 void context_clearPreprocessing (void)
187 {
188   llassert (gc.preprocessing);
189   gc.preprocessing = FALSE;
190 }
191
192 bool context_isPreprocessing (void)
193 {
194   return gc.preprocessing;
195 }
196
197 void context_setInCommandLine (void)
198 {
199   llassert (!gc.incommandline);
200   gc.incommandline = TRUE;
201 }
202
203 void context_clearInCommandLine (void)
204 {
205   llassert (gc.incommandline);
206   gc.incommandline = FALSE;
207 }
208
209 bool context_isInCommandLine (void)
210 {
211   return gc.incommandline;
212 }
213
214 static
215 void 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
238 static
239 clause topClause (clauseStack s) /*@*/
240 {
241   if (clauseStack_isEmpty (s)) return NOCLAUSE;
242   return ((clause) clauseStack_top (s));
243 }
244
245 void
246 context_addMacroCache (/*@only@*/ cstring def)
247 {
248     macrocache_addEntry (gc.mc, fileloc_copy (g_currentloc), def);
249 }
250
251 void
252 context_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
263 static bool
264 context_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
292 static bool
293 context_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
305 bool 
306 context_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
328 bool 
329 context_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
350 bool
351 context_inSuppressZone (fileloc fl) 
352 {
353   if (context_suppressSystemMsg (fl))
354     {
355       return TRUE;
356     }
357
358   return (flagMarkerList_inIgnore (gc.markers, fl));
359 }
360
361 bool
362 context_inSuppressRegion (void)
363 {
364   return (gc.insuppressregion);
365 }
366
367 void
368 context_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
382 static void
383 context_addFlagMarker (flagcode code, ynm set)
384 {
385   flagMarkerList_add (gc.markers,
386                       flagMarker_createLocalSet (code, set, g_currentloc));
387 }
388
389 void
390 context_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
403 void context_checkSuppressCounts (void)
404 {
405   if (context_getFlag (FLG_SUPCOUNTS))
406     {
407       flagMarkerList_checkSuppressCounts (gc.markers);
408     }
409 }
410
411 void context_incLineno (void)
412 {
413   gc.linesprocessed++;
414   incLine ();
415 }
416
417 void
418 context_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
431 void
432 context_enterLCLfile (void)
433 {
434   gc.kind = CX_LCL;
435   gc.facct = typeIdSet_emptySet ();
436 }
437 # endif
438
439 static void
440 addModuleAccess (/*@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
477 static void
478 insertModuleAccess (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
495 void
496 context_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
515 void
516 context_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
532 bool 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
540 bool context_usingAnsiLibrary ()
541 {
542   return (gc.library != FLG_NOLIB);
543 }
544
545 flagcode context_getLibrary ()
546 {
547   return gc.library;
548 }
549
550 void 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
576 void
577 context_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
627 typeIdSet context_fileAccessTypes (void)
628 {
629   return gc.facct;
630 }
631
632 void
633 context_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
656 static void
657 conext_resetAllCounters (void)
658 {
659   int i;
660
661   for (i = 0; i < NUMVALUEFLAGS; i++)
662     {
663       gc.counters[i] = 0;
664     }
665 }
666
667 void
668 context_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
866 void
867 context_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
1223 bool
1224 context_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
1233 bool
1234 context_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
1286 void
1287 context_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
1305 void
1306 context_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
1318 void context_enterFunctionDecl (void)
1319 {
1320   llassert (gc.kind == CX_GLOBAL);
1321   gc.kind = CX_FCNDECL;
1322 }
1323
1324 void context_exitFunctionDecl (void)
1325 {
1326   gc.kind = CX_GLOBAL;
1327 }
1328
1329 bool context_inFunctionDecl (void)
1330 {
1331   return (gc.kind == CX_FCNDECL);
1332 }
1333
1334 void
1335 context_enterMacro (/*@observer@*/ uentry e)
1336 {
1337   context_enterFunction (e);
1338   gc.kind = CX_MACROFCN;
1339 }
1340
1341 void
1342 context_enterUnknownMacro (/*@dependent@*/ uentry e)
1343 {
1344   llassert (uentry_isFunction (e));
1345   context_enterFunction (e);
1346   gc.kind = CX_UNKNOWNMACRO;
1347 }
1348
1349 void context_enterAndClause (exprNode e)
1350 {
1351   
1352   usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
1353   pushClause (ANDCLAUSE);
1354 }
1355
1356 void context_enterOrClause (exprNode e)
1357 {
1358   usymtab_trueBranch (guardSet_invert (exprNode_getGuards (e)));
1359   pushClause (ORCLAUSE);
1360 }
1361
1362 bool 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
1382 bool 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
1402 bool 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
1422 clause 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
1443 clause 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   
1465 bool 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
1483 void 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
1494 void 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
1505 static void context_enterCondClauseAux (clause cl)
1506      /*@modifies gc@*/
1507 {
1508   pushClause (cl);
1509 }
1510
1511 static void context_enterTrueAux (exprNode e, clause cl)
1512    /*@modifies gc@*/
1513 {
1514   usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
1515   pushClause (cl);
1516 }
1517
1518 void context_enterIterClause (void)
1519 {
1520   context_enterTrueAux (exprNode_undefined, ITERCLAUSE);
1521 }
1522
1523 void context_enterDoWhileClause (void)
1524 {
1525   pushClause (DOWHILECLAUSE);
1526 }
1527
1528 void context_enterWhileClause (exprNode e)
1529 {
1530   context_enterTrueAux (e, WHILECLAUSE);
1531 }
1532
1533 void context_enterForClause (exprNode e)
1534 {
1535   context_enterTrueAux (e, FORCLAUSE);
1536 }
1537
1538 void context_enterTrueClause (exprNode e)
1539 {
1540   context_enterTrueAux (e, TRUECLAUSE);
1541 }
1542
1543 void context_enterSwitch (exprNode e)
1544 {
1545   
1546   usymtab_switchBranch (e);
1547   context_enterCondClauseAux (SWITCHCLAUSE);
1548 }
1549
1550 void 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
1562 void 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
1576 static 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
1584 void context_enterFalseClause (exprNode e)
1585 {
1586   
1587   context_enterFalseClauseAux (e, FALSECLAUSE);
1588 }
1589
1590 void
1591 context_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
1609 uentry 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
1620 void
1621 context_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
1636 void
1637 context_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
1665 static bool context_checkStrictGlobals (void)
1666 {
1667   return (context_getFlag (FLG_CHECKSTRICTGLOBALS));
1668 }
1669
1670 static 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
1682 static bool context_checkCheckedGlobals (void)
1683 {
1684   return (context_getFlag (FLG_GLOBALS)
1685           && (context_getFlag (FLG_GLOBUNSPEC)
1686               || context_hasGlobs ()));
1687 }
1688
1689 static 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
1698 static bool context_checkUncheckedGlobals (void)
1699 {
1700   return (FALSE);
1701 }      
1702
1703 bool 
1704 context_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               
1739 bool
1740 context_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
1763 bool
1764 context_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
1786 bool 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
1798 bool
1799 context_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
1837 void
1838 context_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
1854 context_modList (void)
1855 {
1856   return gc.mods;
1857 }
1858
1859 bool
1860 context_globAccess (sRef s)
1861 {
1862   llassert (sRef_isGlobal (s) || sRef_isKindSpecial (s));
1863   return (globSet_member (gc.globs, s));
1864 }
1865
1866 bool
1867 context_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
1879 bool
1880 context_hasFileAccess (typeId t)
1881 {
1882   return (typeIdSet_member (gc.facct, t));
1883 }
1884
1885 /*@only@*/ cstring
1886 context_unparseAccess (void)
1887 {
1888   return (message ("%q / %q", typeIdSet_unparse (gc.acct),
1889                    typeIdSet_unparse (gc.facct)));
1890 }
1891
1892 /*@only@*/ cstring
1893 context_unparseClauses (void)
1894 {
1895   return (clauseStack_unparse (gc.clauses));
1896 }
1897
1898 bool
1899 context_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
1911 ctype
1912 context_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
1942 bool
1943 context_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
1955 void
1956 context_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
1982 static
1983 void context_exitClauseSimp (void)
1984 {
1985   
1986   context_setJustPopped ();
1987   clauseStack_pop (gc.clauses);
1988   gc.inclause = topClause (gc.clauses);
1989 }
1990
1991 static
1992 void context_exitCaseClause (void)
1993 {
1994   context_setJustPopped ();
1995   usymtab_popCaseBranch ();
1996   clauseStack_pop (gc.clauses);
1997   gc.inclause = topClause (gc.clauses);
1998 }
1999
2000 static
2001 void 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
2009 void 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
2027 void 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
2046 static 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
2070 void 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
2107 void 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
2129 void 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
2155 static 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
2170 void 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
2190 void
2191 context_returnFunction (void)
2192 {
2193     usymtab_checkFinalScope (TRUE);
2194   }
2195
2196 void
2197 context_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
2250 void
2251 context_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
2279 context_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
2293 context_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
2301 cstring
2302 context_moduleName ()
2303 {
2304   return (fileloc_getBase (g_currentloc));
2305 }
2306
2307 /*@observer@*/ globSet
2308 context_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
2316 void
2317 context_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
2329 bool
2330 context_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
2354 ctype
2355 context_boolImplementationType () {
2356   /* For now, this is bogus! */
2357   return ctype_int;
2358 }
2359
2360 bool
2361 context_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
2382 void
2383 context_setMessageAnnote (/*@only@*/ cstring s)
2384 {
2385   llassert (cstring_isUndefined (gc.msgAnnote));
2386     gc.msgAnnote = s;
2387 }
2388
2389 bool
2390 context_hasMessageAnnote (void)
2391 {
2392   return (cstring_isDefined (gc.msgAnnote));
2393 }
2394
2395 void
2396 context_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
2406 context_getMessageAnnote (void)
2407 {
2408   cstring st = gc.msgAnnote;
2409
2410     gc.msgAnnote = cstring_undefined;
2411   return st;
2412 }
2413
2414 void
2415 context_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
2423 bool
2424 context_hasAliasAnnote (void)
2425 {
2426   return (sRef_isValid (gc.aliasAnnote));
2427 }
2428
2429 void
2430 context_clearAliasAnnote (void)
2431 {
2432   gc.aliasAnnote = sRef_undefined;
2433 }
2434
2435 cstring
2436 context_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
2447 void
2448 context_recordFileModifies (sRefSet mods)
2449 {
2450     gc.modrecs = sRefSetList_add (gc.modrecs, mods);
2451 }
2452
2453 void
2454 context_recordFileGlobals (globSet mods)
2455 {
2456     /*@access globSet@*/ context_recordFileModifies (mods); /*@noaccess globSet@*/
2457 }
2458
2459 void
2460 context_setCommentMarkerChar (char c)
2461 {
2462   llassert (c != '\0');
2463
2464   context_setValue (FLG_COMMENTCHAR, (int) c);
2465 }
2466
2467 char
2468 context_getCommentMarkerChar (void)
2469 {
2470   return ((char) context_getValue (FLG_COMMENTCHAR));
2471 }
2472
2473 static void
2474 context_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
2518 void
2519 context_setValueAndFlag (flagcode flag, int val)
2520 {
2521   gc.flags[flag] = TRUE;
2522   context_setValue (flag, val);
2523 }
2524
2525 int
2526 context_getValue (flagcode flag)
2527 {
2528   int index = flagcode_valueIndex (flag);
2529
2530   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2531   return (gc.values[index]);
2532 }
2533
2534 int
2535 context_getCounter (flagcode flag)
2536 {
2537   int index = flagcode_valueIndex (flag);
2538
2539   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2540   return (gc.counters[index]);
2541 }
2542
2543 void
2544 context_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
2553 void
2554 context_decCounter (flagcode flag)
2555 {
2556   int index = flagcode_valueIndex (flag);
2557
2558   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2559   gc.counters[index]--;
2560 }
2561
2562 bool context_showFunction (void)
2563 {
2564   return (gc.showfunction);
2565 }
2566
2567 void
2568 context_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
2652 static /*@exposed@*/ cstring
2653 context_exposeString (flagcode flag)
2654 {
2655   int index = flagcode_stringIndex (flag);
2656
2657   llassert (index >= 0 && index <= NUMSTRINGFLAGS);
2658   return (gc.strings[index]);
2659 }
2660
2661 cstring
2662 context_getString (flagcode flag)
2663 {
2664   return (context_exposeString (flag));
2665 }
2666
2667 void
2668 context_resetErrors (void)
2669 {
2670   gc.numerrors = 0;
2671 }
2672
2673 void 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
2741 ctype
2742 context_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
2758 ctype
2759 context_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
2774 context_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
2823 extern ctype
2824 context_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
2843 void
2844 context_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
2865 void
2866 context_exitInnerPlain (void) /*@modifies gc;@*/
2867 {
2868   context_exitInner (exprNode_undefined);
2869 }
2870
2871 void
2872 context_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
2902 void
2903 context_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
2922 void
2923 context_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
2945 void
2946 context_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
2970 static
2971 void 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
3025 static void
3026 context_enterFileAux (void)
3027 {
3028   setModuleAccess ();
3029 }
3030
3031 void
3032 context_enterFile (void)
3033 {
3034   context_enterFileAux ();
3035   usymtab_enterFile ();
3036 }
3037
3038 void
3039 context_enterMacroFile (void)
3040 {
3041   context_enterFileAux ();
3042 }
3043
3044 bool 
3045 context_inFunction (void)
3046 {
3047   kcontext ck = gc.kind;
3048   
3049   return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN) || (ck == CX_INNER));
3050 }
3051
3052 bool 
3053 context_inFunctionLike (void)
3054 {
3055   return (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN 
3056           || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
3057 }
3058
3059 bool 
3060 context_inRealFunction (void)
3061 {
3062   kcontext ck = gc.kind;
3063   
3064   return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN));
3065 }
3066   
3067 void
3068 context_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
3088 static void
3089 context_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
3117 bool
3118 context_processingMacros (void)
3119 {
3120   return (gc.inmacrocache);
3121 }
3122
3123 void
3124 context_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
3178 void
3179 context_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
3207 void
3208 context_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
3217 fileloc
3218 context_getSaveLocation (void)
3219 {
3220   fileloc fl = gc.saveloc;
3221
3222     gc.saveloc = fileloc_undefined;
3223   return fl;
3224 }
3225
3226 /*@observer@*/ cstring
3227 context_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
3243 void
3244 context_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
3325 void
3326 context_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
3348 static void
3349 context_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
3369 static void
3370 context_setFlag (flagcode f, bool b)
3371 {
3372   context_setFlagAux (f, b, FALSE, FALSE);
3373 }
3374
3375 void
3376 context_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
3389 static 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
3666 bool 
3667 context_maybeSet (flagcode d)
3668 {
3669   return (gc.flags[d] || gc.setLocally[d]);
3670 }
3671
3672 bool
3673 context_getFlag (flagcode d)
3674 {
3675   return (gc.flags[d]);
3676 }
3677
3678 static 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
3685 static 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
3692 void 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
3741 void 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
3748 void context_enterIterEnd (/*@observer@*/ uentry le)
3749 {
3750     context_enterMacro (le);
3751   gc.kind = CX_ITEREND;
3752 }
3753
3754 void 
3755 context_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
3793 bool context_msgBoolInt (void)
3794 {
3795   return gc.flags [FLG_BOOLINT];
3796 }
3797
3798 bool context_msgCharInt (void)
3799 {
3800   return gc.flags [FLG_CHARINT];
3801 }
3802
3803 bool context_msgEnumInt (void)
3804 {
3805   return gc.flags [FLG_ENUMINT];
3806 }
3807
3808 bool context_msgPointerArith (void) 
3809 {
3810   return gc.flags [FLG_POINTERARITH];
3811 }
3812
3813 bool context_msgStrictOps (void) 
3814 {
3815   return gc.flags [FLG_STRICTOPS];
3816 }
3817
3818 # ifndef NOLCL
3819 bool context_msgLh (void)           
3820 {
3821   return gc.flags [FLG_DOLH];
3822 }
3823 # endif
3824
3825 void context_pushLoc (void) 
3826 {
3827   fileloc_free (gc.pushloc);
3828   gc.pushloc = gc.saveloc;
3829   gc.saveloc = fileloc_undefined;
3830 }
3831
3832 void context_popLoc (void) 
3833 {
3834   gc.saveloc = fileloc_update (gc.saveloc, gc.pushloc);
3835 }
3836
3837 bool context_inGlobalScope (void)
3838 {
3839   return (usymtab_inFileScope() || usymtab_inGlobalScope ());
3840 }
3841
3842 bool context_inInnerScope (void)
3843 {
3844   return (gc.kind == CX_INNER);
3845 }
3846
3847 void context_setProtectVars (void)
3848 {
3849   gc.protectVars = TRUE;
3850 }
3851
3852 bool context_anyErrors (void)
3853 {
3854   return (gc.numerrors > 0);
3855 }
3856
3857 void context_hasError (void)
3858 {
3859   gc.numerrors++;
3860 }
3861
3862 int context_numErrors (void)
3863 {
3864   return gc.numerrors;
3865 }
3866
3867 bool context_neednl (void)
3868 {
3869   return gc.neednl;
3870 }
3871
3872 void context_setNeednl (void)
3873 {
3874   gc.neednl = TRUE;
3875 }
3876
3877 int context_getExpect (void)
3878 {
3879   return (context_getValue (FLG_EXPECT));
3880 }
3881
3882 # ifndef NOLCL
3883 int context_getLCLExpect (void)
3884 {
3885   return (context_getValue (FLG_LCLEXPECT));
3886 }
3887 # endif
3888
3889 int context_getLimit (void)
3890 {
3891   return (context_getValue (FLG_LIMIT));
3892 }
3893
3894 bool context_unlimitedMessages (void)
3895 {
3896   return (context_getLimit () < 0);
3897 }
3898
3899 void context_releaseVars (void)
3900 {
3901   llassert (gc.protectVars);
3902   gc.protectVars = FALSE;
3903 }
3904
3905 void 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
3914 bool context_inProtectVars (void)
3915 {
3916   return (gc.protectVars);
3917 }
3918
3919 void context_hideShowscan (void) 
3920 {
3921   gc.flags[FLG_SHOWSCAN] = FALSE;
3922 }
3923
3924 void context_unhideShowscan (void)
3925 {
3926   gc.flags[FLG_SHOWSCAN] = TRUE;
3927 }
3928
3929 bool context_inHeader (void)
3930 {
3931   return (gc.inheader);
3932 }
3933
3934 fileTable context_fileTable (void)
3935 {
3936   return gc.ftab;
3937 }
3938
3939 cstring context_tmpdir (void)
3940 {
3941   return (context_getString (FLG_TMPDIR));
3942 }
3943
3944 messageLog context_messageLog (void)
3945 {
3946   return gc.msgLog;
3947 }
3948
3949 bool context_inMacroFunction (void)
3950 {
3951   return (gc.kind == CX_MACROFCN);
3952 }
3953
3954 bool context_inMacroConstant (void)
3955 {   
3956   return (gc.kind == CX_MACROCONST);
3957 }
3958
3959 bool context_inMacroUnknown (void)
3960 {   
3961   return (gc.kind == CX_UNKNOWNMACRO);
3962 }
3963
3964 void context_setShownFunction (void)
3965 {
3966   gc.showfunction = FALSE;
3967 }
3968
3969 bool context_doDump (void)
3970 {   
3971   return cstring_isNonEmpty (context_getString (FLG_DUMP));
3972 }
3973
3974 bool context_doMerge (void)
3975 {
3976   return cstring_isNonEmpty (context_getString (FLG_MERGE));
3977 }
3978
3979 cstring context_getDump (void)
3980 {           
3981   return context_getString (FLG_DUMP);
3982 }
3983
3984 cstring context_getMerge (void)
3985 {
3986   return context_getString (FLG_MERGE);
3987 }
3988
3989 # ifndef NOLCL
3990 bool context_inLCLLib (void)
3991 {   
3992   return (gc.kind == CX_LCLLIB);
3993 }
3994
3995 bool context_inImport (void)
3996 {
3997   return (gc.inimport);
3998 }
3999
4000 void context_enterImport (void)
4001
4002   gc.inimport = TRUE;
4003 }
4004
4005 void context_leaveImport (void)
4006
4007   gc.inimport = FALSE;
4008 }
4009 # endif
4010
4011 bool 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
4018 bool context_inIterDef (void)
4019 {
4020   return (gc.kind == CX_ITERDEF);
4021 }
4022
4023 bool context_inIterEnd (void)
4024 {
4025   return (gc.kind == CX_ITEREND);
4026 }
4027
4028 int context_getLinesProcessed (void)    
4029 {
4030   return (gc.linesprocessed);
4031 }
4032
4033 int context_getSpecLinesProcessed (void)    
4034 {
4035   return (gc.speclinesprocessed);
4036 }
4037
4038 # ifndef NOLCL
4039 void context_processedSpecLine (void)
4040 {
4041   gc.speclinesprocessed++;
4042 }
4043
4044 void context_resetSpecLines (void)    
4045 {
4046   gc.speclinesprocessed = 0;
4047 }
4048 # endif
4049
4050 bool context_inGlobalContext (void)
4051 {
4052   return (gc.kind == CX_GLOBAL);
4053 }
4054
4055 void context_setFileId (fileId s)
4056 {
4057   g_currentloc = fileloc_updateFileId (g_currentloc, s); 
4058 }
4059
4060 bool context_setBoolName (void)
4061 {
4062   return (!cstring_equalLit (context_getString (FLG_BOOLTYPE),
4063                              DEFAULT_BOOLTYPE));
4064 }
4065
4066 cstring 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
4078 cstring context_getBoolName (void)
4079 {
4080   return (context_getString (FLG_BOOLTYPE));
4081 }
4082
4083 cstring context_getFalseName (void)
4084 {
4085   return (context_getString (FLG_BOOLFALSE));
4086 }
4087
4088 cstring context_getTrueName (void)
4089 {
4090   return (context_getString (FLG_BOOLTRUE));
4091 }
4092
4093 cstring context_getLarchPath (void)
4094 {
4095   return (context_getString (FLG_LARCHPATH));
4096 }
4097
4098 cstring context_getLCLImportDir (void)
4099 {
4100   return (context_getString (FLG_LCLIMPORTDIR));
4101 }
4102
4103 static void context_setJustPopped (void)
4104 {
4105   gc.justpopped = TRUE;
4106 }
4107
4108 void context_clearJustPopped (void)
4109 {
4110   gc.justpopped = FALSE;
4111 }
4112
4113 bool context_justPopped (void)
4114 {
4115   return (gc.justpopped);
4116 }
4117
4118 void context_setMacroMissingParams (void)
4119 {
4120   gc.macroMissingParams = TRUE;
4121 }
4122
4123 void context_resetMacroMissingParams (void)
4124 {
4125   gc.macroMissingParams = FALSE;
4126 }
4127
4128 bool context_isMacroMissingParams (void)
4129 {
4130   return (gc.macroMissingParams);
4131 }
4132
4133 void context_showFilelocStack (void) 
4134 {
4135   filelocStack_printIncludes (gc.locstack);
4136 }
4137
4138
4139
4140
4141
4142
4143
This page took 0.67142 seconds and 5 git commands to generate.