00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 # include "lclintMacros.nf"
00037 # include "llbasic.h"
00038
00039 # ifndef NOLCL
00040 # include "usymtab_interface.h"
00041 # endif
00042
00043 # include "exprChecks.h"
00044 # include "filelocStack.h"
00045 # include "fileIdList.h"
00046 # include "llmain.h"
00047 # include "intSet.h"
00048 # include "osd.h"
00049 # include "portab.h"
00050
00051 extern int yydebug;
00052
00053 typedef struct
00054 {
00055 cstring file;
00056 typeIdSet daccess ;
00057 } maccesst;
00058
00059 typedef enum {
00060 CX_GLOBAL, CX_INNER,
00061 CX_FUNCTION, CX_FCNDECL,
00062 CX_MACROFCN, CX_MACROCONST, CX_UNKNOWNMACRO,
00063 CX_ITERDEF, CX_ITEREND,
00064 CX_LCL, CX_LCLLIB
00065 } kcontext;
00066
00067 static struct _context
00068 {
00069 int linesprocessed;
00070 int speclinesprocessed;
00071
00072 flagMarkerList markers;
00073
00074
00075
00076
00077
00078
00079 bool macroMissingParams BOOLBITS;
00080 bool preprocessing BOOLBITS;
00081 bool incommandline BOOLBITS;
00082 bool insuppressregion BOOLBITS;
00083 bool inDerivedFile BOOLBITS;
00084 bool instandardlib BOOLBITS;
00085 bool inimport BOOLBITS;
00086 bool inheader BOOLBITS;
00087 bool inmacrocache BOOLBITS;
00088 bool protectVars BOOLBITS;
00089 bool neednl BOOLBITS;
00090 bool showfunction BOOLBITS;
00091 bool savedFlags BOOLBITS;
00092 bool justpopped BOOLBITS;
00093 bool anyExports BOOLBITS;
00094
00095 flagcode library;
00096
00097 ynm isNullGuarded;
00098 fileloc saveloc;
00099 fileloc pushloc;
00100
00101 clauseStack clauses;
00102 clause inclause;
00103
00104 int numerrors;
00105
00106 filelocStack locstack;
00107 fileTable ftab;
00108 cstring msgAnnote;
00109 sRef aliasAnnote;
00110 sRef aliasAnnoteAls;
00111 messageLog msgLog;
00112
00113 macrocache mc;
00114 sRefSet mods;
00115
00116
00117 typeIdSet facct;
00118
00119
00120 typeIdSet acct;
00121
00122
00123 typeIdSet nacct;
00124
00125 globSet globs;
00126 globSet globs_used;
00127
00128 int nmods;
00129 int maxmods;
00130 maccesst *moduleaccess;
00131
00132 kcontext kind;
00133
00134 ctype boolType;
00135
00136 bool flags[NUMFLAGS];
00137 bool saveflags[NUMFLAGS];
00138 bool setGlobally[NUMFLAGS];
00139 bool setLocally[NUMFLAGS];
00140
00141 int values[NUMVALUEFLAGS];
00142 int counters[NUMVALUEFLAGS];
00143
00144 o_cstring strings[NUMSTRINGFLAGS];
00145 sRefSetList modrecs;
00146
00147 union
00148 {
00149 bool glob;
00150 int cdepth;
00151 uentry fcn;
00152 } cont;
00153 } gc;
00154
00155 static cstring context_exposeString (flagcode p_flag) ;
00156 static void context_restoreFlagSettings (void) ;
00157 static void context_saveFlagSettings (void) ;
00158 static void context_exitClauseAux (exprNode p_pred, exprNode p_tbranch)
00159 ;
00160 static void context_exitClauseSimp (void) ;
00161 static void context_exitClausePlain (void) ;
00162 static void context_setJustPopped (void) ;
00163 static void context_setValue (flagcode p_flag, int p_val) ;
00164 static void context_setFlag (flagcode p_f, bool p_b)
00165 ;
00166
00167 static void
00168 context_setFlagAux (flagcode p_f, bool p_b, bool p_inFile, bool p_isRestore)
00169 ;
00170
00171 static void context_restoreFlag (flagcode p_f) ;
00172
00173
00174
00175 cstring context_unparseFlagMarkers ()
00176 {
00177 return (flagMarkerList_unparse (gc.markers));
00178 }
00179
00180 void context_setPreprocessing (void)
00181 {
00182 llassert (!gc.preprocessing);
00183 gc.preprocessing = TRUE;
00184 }
00185
00186 void context_clearPreprocessing (void)
00187 {
00188 llassert (gc.preprocessing);
00189 gc.preprocessing = FALSE;
00190 }
00191
00192 bool context_isPreprocessing (void)
00193 {
00194 return gc.preprocessing;
00195 }
00196
00197 void context_setInCommandLine (void)
00198 {
00199 llassert (!gc.incommandline);
00200 gc.incommandline = TRUE;
00201 }
00202
00203 void context_clearInCommandLine (void)
00204 {
00205 llassert (gc.incommandline);
00206 gc.incommandline = FALSE;
00207 }
00208
00209 bool context_isInCommandLine (void)
00210 {
00211 return gc.incommandline;
00212 }
00213
00214 static
00215 void pushClause (clause c)
00216 {
00217 gc.inclause = c;
00218 clauseStack_push (gc.clauses, c);
00219
00220 if (clause_isConditional (c)
00221 && context_getFlag (FLG_CONTROLNESTDEPTH))
00222 {
00223 int maxdepth = context_getValue (FLG_CONTROLNESTDEPTH);
00224 int depth = clauseStack_controlDepth (gc.clauses);
00225
00226 if (depth == maxdepth + 1)
00227 {
00228 voptgenerror
00229 (FLG_CONTROLNESTDEPTH,
00230 message ("Maximum control nesting depth "
00231 "(%d) exceeded",
00232 maxdepth),
00233 g_currentloc);
00234 }
00235 }
00236 }
00237
00238 static
00239 clause topClause (clauseStack s)
00240 {
00241 if (clauseStack_isEmpty (s)) return NOCLAUSE;
00242 return ((clause) clauseStack_top (s));
00243 }
00244
00245 void
00246 context_addMacroCache ( cstring def)
00247 {
00248 macrocache_addEntry (gc.mc, fileloc_copy (g_currentloc), def);
00249 }
00250
00251 void
00252 context_addComment ( cstring def)
00253 {
00254 macrocache_addComment (gc.mc, fileloc_copy (g_currentloc), def);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263 static bool
00264 context_inSuppressFlagZone (fileloc fl, flagcode code)
00265 {
00266 ynm ret = flagMarkerList_suppressError (gc.markers, code, fl);
00267 bool res = FALSE;
00268
00269 if (ynm_isMaybe (ret))
00270 {
00271
00272
00273
00274
00275 if (gc.savedFlags)
00276 {
00277 res = !gc.saveflags[code];
00278 }
00279 else
00280 {
00281 res = !context_getFlag (code);
00282 }
00283 }
00284 else
00285 {
00286 res = ynm_toBoolStrict (ret);
00287 }
00288
00289 return res;
00290 }
00291
00292 static bool
00293 context_suppressSystemMsg (fileloc fl)
00294 {
00295 if (context_getFlag (FLG_SYSTEMDIRERRORS))
00296 {
00297 return FALSE;
00298 }
00299 else
00300 {
00301 return (fileloc_isSystemFile (fl));
00302 }
00303 }
00304
00305 bool
00306 context_suppressFlagMsg (flagcode flag, fileloc fl)
00307 {
00308 if (context_suppressSystemMsg (fl))
00309 {
00310 return TRUE;
00311 }
00312
00313
00314
00315 if (fileloc_equal (fl, g_currentloc) || gc.inDerivedFile)
00316 {
00317 return (!context_getFlag (flag)
00318 || context_inSuppressRegion ()
00319 || context_inSuppressZone (fl)
00320 || (gc.inDerivedFile && context_inSuppressFlagZone (fl, flag)));
00321 }
00322 else
00323 {
00324 return (context_inSuppressFlagZone (fl, flag));
00325 }
00326 }
00327
00328 bool
00329 context_suppressNotFlagMsg (flagcode flag, fileloc fl)
00330 {
00331
00332 if (context_suppressSystemMsg (fl))
00333 {
00334 return TRUE;
00335 }
00336
00337
00338 if (fl == g_currentloc)
00339
00340 {
00341 return (context_getFlag (flag) || context_inSuppressRegion ());
00342 }
00343 else
00344 {
00345
00346 return (context_getFlag (flag) || context_inSuppressRegion ());
00347 }
00348 }
00349
00350 bool
00351 context_inSuppressZone (fileloc fl)
00352 {
00353 if (context_suppressSystemMsg (fl))
00354 {
00355 return TRUE;
00356 }
00357
00358 return (flagMarkerList_inIgnore (gc.markers, fl));
00359 }
00360
00361 bool
00362 context_inSuppressRegion (void)
00363 {
00364 return (gc.insuppressregion);
00365 }
00366
00367 void
00368 context_enterSuppressRegion (void)
00369 {
00370 if (gc.insuppressregion)
00371 {
00372 gc.insuppressregion = FALSE;
00373 llmsg (message
00374 ("%q: New ignore errors region entered while in ignore errors region",
00375 fileloc_unparse (g_currentloc)));
00376 }
00377
00378 gc.insuppressregion = TRUE;
00379 flagMarkerList_add (gc.markers, flagMarker_createIgnoreOn (g_currentloc));
00380 }
00381
00382 static void
00383 context_addFlagMarker (flagcode code, ynm set)
00384 {
00385 flagMarkerList_add (gc.markers,
00386 flagMarker_createLocalSet (code, set, g_currentloc));
00387 }
00388
00389 void
00390 context_enterSuppressLine (int count)
00391 {
00392 fileloc nextline = fileloc_copy (g_currentloc);
00393
00394 flagMarkerList_add (gc.markers,
00395 flagMarker_createIgnoreCount (count, g_currentloc));
00396
00397 fileloc_nextLine (nextline);
00398 flagMarkerList_add (gc.markers,
00399 flagMarker_createIgnoreOff (nextline));
00400 fileloc_free (nextline);
00401 }
00402
00403 void context_checkSuppressCounts (void)
00404 {
00405 if (context_getFlag (FLG_SUPCOUNTS))
00406 {
00407 flagMarkerList_checkSuppressCounts (gc.markers);
00408 }
00409 }
00410
00411 void context_incLineno (void)
00412 {
00413 gc.linesprocessed++;
00414 incLine ();
00415 }
00416
00417 void
00418 context_exitSuppressRegion (void)
00419 {
00420 if (!gc.insuppressregion)
00421 {
00422 llerrorlit (FLG_SYNTAX,
00423 "End ignore errors in region while not ignoring errors");
00424 }
00425
00426 gc.insuppressregion = FALSE;
00427 flagMarkerList_add (gc.markers, flagMarker_createIgnoreOff (g_currentloc));
00428 }
00429
00430 # ifndef NOLCL
00431 void
00432 context_enterLCLfile (void)
00433 {
00434 gc.kind = CX_LCL;
00435 gc.facct = typeIdSet_emptySet ();
00436 }
00437 # endif
00438
00439 static void
00440 addModuleAccess ( cstring fname, typeIdSet mods)
00441 {
00442 int i;
00443
00444 for (i = 0; i < gc.nmods; i++)
00445 {
00446 if (cstring_equal (gc.moduleaccess[i].file, fname))
00447 {
00448 gc.moduleaccess[i].daccess = typeIdSet_union (gc.moduleaccess[i].daccess, mods);
00449 cstring_free (fname);
00450 return;
00451 }
00452 }
00453
00454 if (gc.nmods == gc.maxmods)
00455 {
00456 maccesst *oldmods;
00457
00458 gc.maxmods = gc.maxmods + DEFAULTMAXMODS;
00459 oldmods = gc.moduleaccess;
00460
00461 gc.moduleaccess = (maccesst *) dmalloc (sizeof (*gc.moduleaccess) * (gc.maxmods));
00462
00463 for (i = 0; i < gc.nmods; i++)
00464 {
00465 gc.moduleaccess[i] = oldmods[i];
00466 }
00467
00468 sfree (oldmods);
00469 }
00470
00471 gc.moduleaccess[gc.nmods].file = fname;
00472 gc.moduleaccess[gc.nmods].daccess = mods;
00473
00474 gc.nmods++;
00475 }
00476
00477 static void
00478 insertModuleAccess (cstring fname, typeId t)
00479 {
00480 int i;
00481
00482 for (i = 0; i < gc.nmods; i++)
00483 {
00484 if (cstring_equal (gc.moduleaccess[i].file, fname))
00485 {
00486 gc.moduleaccess[i].daccess = typeIdSet_insert (gc.moduleaccess[i].daccess, t);
00487 break;
00488 }
00489 }
00490
00491 addModuleAccess (cstring_copy (fname), typeIdSet_single (t));
00492 }
00493
00494 # ifndef NOLCL
00495 void
00496 context_exitLCLfile (void)
00497 {
00498 if (gc.kind != CX_LCLLIB)
00499 {
00500 char *lclname =
00501 removeExtension (cstring_toCharsSafe
00502 (fileName (currentFile ())), ".lcl");
00503
00504 addModuleAccess (cstring_fromCharsO (removePath (lclname)), gc.facct);
00505
00506 mstring_free (lclname);
00507 }
00508
00509 gc.kind = CX_LCL;
00510 gc.kind = CX_GLOBAL;
00511 gc.facct = typeIdSet_emptySet ();
00512 }
00513 # endif
00514
00515 void
00516 context_dumpModuleAccess (FILE *fout)
00517 {
00518 int i = 0;
00519
00520 for (i = 0; i < gc.nmods; i++)
00521 {
00522 cstring td = typeIdSet_dump (gc.moduleaccess[i].daccess);
00523
00524 fprintf (fout, "%s#%s@\n",
00525 cstring_toCharsSafe (gc.moduleaccess[i].file),
00526 cstring_toCharsSafe (td));
00527
00528 cstring_free (td);
00529 }
00530 }
00531
00532 bool context_usingPosixLibrary ()
00533 {
00534 return (gc.library == FLG_POSIXLIB
00535 || gc.library == FLG_POSIXSTRICTLIB
00536 || gc.library == FLG_UNIXLIB
00537 || gc.library == FLG_UNIXSTRICTLIB);
00538 }
00539
00540 bool context_usingAnsiLibrary ()
00541 {
00542 return (gc.library != FLG_NOLIB);
00543 }
00544
00545 flagcode context_getLibrary ()
00546 {
00547 return gc.library;
00548 }
00549
00550 void context_setLibrary (flagcode code)
00551 {
00552 gc.library = code;
00553 }
00554
00555 char *context_selectedLibrary ()
00556 {
00557 switch (gc.library)
00558 {
00559 case FLG_STRICTLIB:
00560 return LLSTRICTLIBS_NAME;
00561 case FLG_POSIXLIB:
00562 return LLPOSIXLIBS_NAME;
00563 case FLG_POSIXSTRICTLIB:
00564 return LLPOSIXSTRICTLIBS_NAME;
00565 case FLG_UNIXLIB:
00566 return LLUNIXLIBS_NAME;
00567 case FLG_UNIXSTRICTLIB:
00568 return LLUNIXSTRICTLIBS_NAME;
00569 case FLG_ANSILIB:
00570 return LLSTDLIBS_NAME;
00571 BADDEFAULT;
00572 }
00573 }
00574
00575
00576 void
00577 context_loadModuleAccess (FILE *in)
00578 {
00579 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
00580 char *lasts = s;
00581 char *name = mstring_create (MAX_NAME_LENGTH);
00582 char *oname = name;
00583 # ifndef NOFREE
00584 char *os = s;
00585 # endif
00586
00587 while (fgets (s, MAX_DUMP_LINE_LENGTH, in) != NULL
00588 && *s == ';')
00589 {
00590 ;
00591 }
00592
00593 while (s != NULL && *s != ';' && *s != '\0')
00594 {
00595 name = oname;
00596
00597 while (*s != '#' && *s != '\0')
00598 {
00599 *name++ = *s++;
00600 }
00601
00602 *name = '\0';
00603
00604 if (*s != '#')
00605 {
00606 llcontbug (message ("context_loadModuleAccess: bad library line: %s\n",
00607 cstring_fromChars (s)));
00608 break;
00609 }
00610
00611 s++;
00612
00613 addModuleAccess (cstring_copy (cstring_fromChars (oname)),
00614 typeIdSet_undump (&s));
00615
00616 (void) fgets (s, MAX_DUMP_LINE_LENGTH, in);
00617 llassert (s != lasts);
00618 lasts = s;
00619 }
00620
00621 sfree (oname);
00622 # ifndef NOFREE
00623 sfree (os);
00624 # endif
00625 }
00626
00627 typeIdSet context_fileAccessTypes (void)
00628 {
00629 return gc.facct;
00630 }
00631
00632 void
00633 context_resetModeFlags (void)
00634 {
00635
00636 allFlagCodes (code)
00637 {
00638 if (flagcode_isModeFlag (code))
00639 {
00640 context_setFlag (code, FALSE);
00641 }
00642 } end_allFlagCodes;
00643
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 static void
00657 conext_resetAllCounters (void)
00658 {
00659 int i;
00660
00661 for (i = 0; i < NUMVALUEFLAGS; i++)
00662 {
00663 gc.counters[i] = 0;
00664 }
00665 }
00666
00667 void
00668 context_resetAllFlags (void)
00669 {
00670 allFlagCodes (code)
00671 {
00672 gc.flags[code] = FALSE;
00673
00674 if (flagcode_hasValue (code))
00675 {
00676 int val = 0;
00677
00678
00679 switch (code)
00680 {
00681 case FLG_LIMIT:
00682 val = DEFAULT_LIMIT; break;
00683 case FLG_LINELEN:
00684 val = DEFAULT_LINELEN; break;
00685 case FLG_EXTERNALNAMELEN:
00686 val = DEFAULT_EXTERNALNAMELEN; break;
00687 case FLG_INTERNALNAMELEN:
00688 val = DEFAULT_INTERNALNAMELEN; break;
00689 case FLG_COMMENTCHAR:
00690 val = (int) DEFAULT_COMMENTCHAR; break;
00691 case FLG_CONTROLNESTDEPTH:
00692 val = (int) DEFAULT_CONTROLNESTDEPTH; break;
00693 case FLG_STRINGLITERALLEN:
00694 val = (int) DEFAULT_STRINGLITERALLEN; break;
00695 case FLG_INCLUDENEST:
00696 val = (int) DEFAULT_INCLUDENEST; break;
00697 case FLG_NUMSTRUCTFIELDS:
00698 val = (int) DEFAULT_NUMSTRUCTFIELDS; break;
00699 case FLG_NUMENUMMEMBERS:
00700 val = (int) DEFAULT_NUMENUMMEMBERS; break;
00701 case FLG_EXPECT:
00702 case FLG_LCLEXPECT:
00703 break;
00704 default:
00705 llbug (message ("Bad value flag: %s", flagcode_unparse (code)));
00706 }
00707
00708
00709 context_setValue (code, val);
00710 }
00711 else if (flagcode_hasString (code))
00712 {
00713 cstring val = cstring_undefined;
00714
00715 switch (code)
00716 {
00717 case FLG_LARCHPATH:
00718 {
00719 char *larchpath = osd_getEnvironmentVariable (LARCH_PATH);
00720
00721 if (larchpath != NULL)
00722 {
00723 val = cstring_fromCharsNew (larchpath);
00724 }
00725 else
00726 {
00727 val = cstring_makeLiteral (DEFAULT_LARCHPATH);
00728 }
00729
00730 break;
00731 }
00732 case FLG_LCLIMPORTDIR:
00733 {
00734 val = cstring_fromCharsNew (osd_getEnvironment (LCLIMPORTDIR, DEFAULT_LCLIMPORTDIR));
00735 break;
00736 }
00737 case FLG_TMPDIR:
00738 # if defined(OS2) || defined(MSDOS) || defined(WIN32)
00739 {
00740 char *env = osd_getEnvironmentVariable ("TMP");
00741
00742 if (env == NULL)
00743 {
00744 env = osd_getEnvironmentVariable ("TEMP");
00745 }
00746
00747 val = cstring_makeLiteral (env != NULL ? env : DEFAULT_TMPDIR);
00748 }
00749 # else
00750 val = cstring_makeLiteral (DEFAULT_TMPDIR);
00751 # endif
00752
00753 break;
00754 case FLG_BOOLTYPE:
00755 val = cstring_makeLiteral (DEFAULT_BOOLTYPE); break;
00756 case FLG_BOOLFALSE:
00757 val = cstring_makeLiteral ("FALSE"); break;
00758 case FLG_BOOLTRUE:
00759 val = cstring_makeLiteral ("TRUE"); break;
00760 case FLG_MACROVARPREFIX:
00761 val = cstring_makeLiteral ("m_"); break;
00762 case FLG_SYSTEMDIRS:
00763 val = cstring_makeLiteral (DEFAULT_SYSTEMDIR); break;
00764 default:
00765 break;
00766 }
00767
00768 context_setString (code, val);
00769 }
00770 else
00771 {
00772 ;
00773 }
00774 } end_allFlagCodes;
00775
00776
00777
00778
00779
00780 gc.flags[FLG_MODIFIES] = TRUE;
00781 gc.flags[FLG_NESTCOMMENT] = TRUE;
00782 gc.flags[FLG_GLOBALS] = TRUE;
00783 gc.flags[FLG_FULLINITBLOCK] = TRUE;
00784 gc.flags[FLG_LIKELYBOOL] = TRUE;
00785 gc.flags[FLG_ZEROPTR] = TRUE;
00786 gc.flags[FLG_NUMLITERAL] = TRUE;
00787 gc.flags[FLG_DUPLICATEQUALS] = TRUE;
00788 gc.flags[FLG_SKIPANSIHEADERS] = TRUE;
00789 gc.flags[FLG_SKIPPOSIXHEADERS] = TRUE;
00790 gc.flags[FLG_SYSTEMDIREXPAND] = TRUE;
00791 gc.flags[FLG_UNRECOGCOMMENTS] = TRUE;
00792 gc.flags[FLG_CASTFCNPTR] = TRUE;
00793 gc.flags[FLG_DOLCS] = TRUE;
00794 gc.flags[FLG_USEVARARGS] = TRUE;
00795 gc.flags[FLG_MAINTYPE] = TRUE;
00796 gc.flags[FLG_SPECMACROS] = TRUE;
00797 gc.flags[FLG_REDEF] = TRUE;
00798 gc.flags[FLG_MACRONEXTLINE] = TRUE;
00799
00800 gc.flags[FLG_SIZEOFFORMALARRAY] = TRUE;
00801 gc.flags[FLG_FIXEDFORMALARRAY] = TRUE;
00802
00803 gc.flags[FLG_PREDASSIGN] = TRUE;
00804 gc.flags[FLG_MODOBSERVER] = TRUE;
00805 gc.flags[FLG_MACROVARPREFIXEXCLUDE] = TRUE;
00806 gc.flags[FLG_EXTERNALNAMECASEINSENSITIVE] = TRUE;
00807
00808 gc.flags[FLG_PARAMIMPTEMP] = TRUE;
00809 gc.flags[FLG_RETIMPONLY] = TRUE;
00810 gc.flags[FLG_GLOBIMPONLY] = TRUE;
00811 gc.flags[FLG_STRUCTIMPONLY] = TRUE;
00812 gc.flags[FLG_PREPROC] = TRUE;
00813 gc.flags[FLG_NAMECHECKS] = TRUE;
00814 gc.flags[FLG_FORMATCODE] = TRUE;
00815 gc.flags[FLG_FORMATTYPE] = TRUE;
00816 gc.flags[FLG_BADFLAG] = TRUE;
00817 gc.flags[FLG_WARNFLAGS] = TRUE;
00818 gc.flags[FLG_WARNUNIXLIB] = TRUE;
00819 gc.flags[FLG_WARNPOSIX] = TRUE;
00820 gc.flags[FLG_SHOWCOL] = TRUE;
00821 gc.flags[FLG_SHOWFUNC] = TRUE;
00822 gc.flags[FLG_SUPCOUNTS] = TRUE;
00823 gc.flags[FLG_HINTS] = TRUE;
00824 gc.flags[FLG_SYNTAX] = TRUE;
00825 gc.flags[FLG_TYPE] = TRUE;
00826 gc.flags[FLG_INCOMPLETETYPE] = TRUE;
00827 gc.flags[FLG_ABSTRACT] = TRUE;
00828 gc.flags[FLG_ITER] = TRUE;
00829 gc.flags[FLG_CONTROL] = TRUE;
00830 gc.flags[FLG_UNRECOG] = TRUE;
00831 gc.flags[FLG_SYSTEMUNRECOG] = TRUE;
00832 gc.flags[FLG_LINTCOMMENTS] = TRUE;
00833 gc.flags[FLG_ACCESSCZECH] = TRUE;
00834 gc.flags[FLG_ACCESSMODULE] = TRUE;
00835 gc.flags[FLG_ACCESSFILE] = TRUE;
00836 gc.flags[FLG_MACROVARPREFIX] = TRUE;
00837
00838
00839
00840
00841
00842 gc.flags[FLG_GNUEXTENSIONS] = TRUE;
00843
00844
00845
00846
00847
00848 # ifdef WIN32
00849 gc.flags[FLG_PARENFILEFORMAT] = TRUE;
00850 # endif
00851 }
00852
00853
00854
00855
00856
00857
00858
00859 # define SETFLAGS() \
00860 { int i = 0; while (modeflags[i] != INVALID_FLAG) { \
00861 if (!flagcode_isModeFlag (modeflags[i])) \
00862 { llbug (message ("not a mode flag: %s", \
00863 flagcode_unparse (modeflags[i]))); } \
00864 else { context_setFlag (modeflags[i], TRUE); } i++; }}
00865
00866 void
00867 context_setMode (cstring s)
00868 {
00869 intSet setflags = intSet_new ();
00870
00871 allFlagCodes (code)
00872 {
00873 if (flagcode_isModeFlag (code))
00874 {
00875 if (gc.setGlobally[code])
00876 {
00877 (void) intSet_insert (setflags, (int) code);
00878 }
00879 }
00880 } end_allFlagCodes;
00881
00882 if (!intSet_isEmpty (setflags))
00883 {
00884 cstring rflags = cstring_undefined;
00885 int num = 0;
00886
00887 intSet_elements (setflags, el)
00888 {
00889 if (cstring_isUndefined (rflags))
00890 {
00891 rflags = cstring_copy (flagcode_unparse ((flagcode) (el)));
00892 }
00893 else
00894 {
00895 rflags = message ("%q, %s", rflags,
00896 flagcode_unparse ((flagcode) el));
00897 }
00898
00899 num++;
00900 if (num > 4 && intSet_size (setflags) > 6)
00901 {
00902 rflags = message ("%q, (%d others) ...", rflags,
00903 intSet_size (setflags) - num);
00904 break;
00905 }
00906 } end_intSet_elements ;
00907
00908 voptgenerror (FLG_WARNFLAGS,
00909 message ("Setting mode %s after setting mode flags will "
00910 "override set values of flags: %s",
00911 s, rflags),
00912 g_currentloc);
00913
00914 cstring_free (rflags);
00915 }
00916
00917 intSet_free (setflags);
00918
00919 context_resetModeFlags ();
00920
00921 if (cstring_equalLit (s, "standard"))
00922 {
00923 flagcode modeflags[] =
00924 {
00925 FLG_ENUMINT, FLG_MACROMATCHNAME,
00926 FLG_MACROUNDEF, FLG_RELAXQUALS,
00927 FLG_USEALLGLOBS, FLG_CHECKSTRICTGLOBALS,
00928 FLG_CHECKSTRICTGLOBALIAS,
00929 FLG_CHECKEDGLOBALIAS,
00930 FLG_CHECKMODGLOBALIAS,
00931 FLG_PREDBOOLOTHERS, FLG_PREDBOOLINT,
00932 FLG_PARAMUNUSED, FLG_VARUNUSED, FLG_FUNCUNUSED,
00933 FLG_TYPEUNUSED,
00934 FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED, FLG_FIELDUNUSED,
00935 FLG_PTRNUMCOMPARE, FLG_BOOLCOMPARE, FLG_MUTREP,
00936 FLG_NOEFFECT, FLG_IMPTYPE,
00937 FLG_RETVALOTHER, FLG_RETVALBOOL, FLG_RETVALINT,
00938 FLG_SPECUNDEF, FLG_INCONDEFS, FLG_INCONDEFSLIB,
00939 FLG_MATCHFIELDS,
00940 FLG_MACROPARAMS, FLG_MACROASSIGN, FLG_SEFPARAMS,
00941 FLG_MACROSTMT, FLG_MACROPARENS,
00942 FLG_MACROFCNDECL,
00943 FLG_MACROCONSTDECL,
00944 FLG_MACROREDEF, FLG_INFLOOPS, FLG_UNREACHABLE,
00945 FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE, FLG_USEDEF,
00946 FLG_FIRSTCASE,
00947 FLG_NESTEDEXTERN,
00948 FLG_NUMLITERAL,
00949 FLG_ZEROBOOL,
00950
00951 FLG_NULLDEREF,
00952 FLG_NULLSTATE, FLG_NULLASSIGN,
00953 FLG_NULLPASS, FLG_NULLRET,
00954
00955 FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF,
00956 FLG_RETSTACK,
00957
00958
00959 FLG_EXPOSETRANS,
00960 FLG_OBSERVERTRANS,
00961 FLG_DEPENDENTTRANS,
00962 FLG_NEWREFTRANS,
00963 FLG_ONLYTRANS,
00964 FLG_OWNEDTRANS,
00965 FLG_FRESHTRANS,
00966 FLG_SHAREDTRANS,
00967 FLG_TEMPTRANS,
00968 FLG_KEPTTRANS,
00969 FLG_REFCOUNTTRANS,
00970 FLG_STATICTRANS,
00971 FLG_UNKNOWNTRANS,
00972 FLG_KEEPTRANS,
00973 FLG_IMMEDIATETRANS,
00974
00975 FLG_EXPORTLOCAL,
00976
00977 FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
00978 FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE,
00979 FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
00980 FLG_MEMIMPLICIT,
00981 FLG_BRANCHSTATE,
00982
00983 FLG_EVALORDER, FLG_SHADOW, FLG_READONLYSTRINGS,
00984 FLG_EXITARG,
00985 FLG_IMPCHECKEDSPECGLOBALS,
00986 FLG_MODGLOBS, FLG_WARNLINTCOMMENTS,
00987 FLG_IFEMPTY, FLG_REALCOMPARE,
00988 FLG_BOOLOPS, FLG_PTRNEGATE,
00989 FLG_SHIFTSIGNED,
00990 INVALID_FLAG } ;
00991
00992 SETFLAGS ();
00993 }
00994 else if (cstring_equalLit (s, "weak"))
00995 {
00996 flagcode modeflags[] =
00997 {
00998 FLG_BOOLINT, FLG_CHARINT, FLG_FLOATDOUBLE,
00999 FLG_ENUMINT, FLG_RELAXQUALS, FLG_FORWARDDECL,
01000 FLG_CHARINDEX, FLG_ABSTVOIDP, FLG_USEALLGLOBS,
01001 FLG_CHARUNSIGNEDCHAR,
01002 FLG_PREDBOOLOTHERS,
01003 FLG_VARUNUSED, FLG_FUNCUNUSED,
01004 FLG_TYPEUNUSED,
01005 FLG_CHECKSTRICTGLOBALS, FLG_MACROMATCHNAME,
01006 FLG_RETVALOTHER,
01007 FLG_IFEMPTY,
01008 FLG_RETSTACK, FLG_PTRNEGATE,
01009 FLG_LONGUNSIGNEDINTEGRAL,
01010 FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL,
01011 FLG_NUMLITERAL,
01012 FLG_CHARINTLITERAL,
01013 FLG_ZEROBOOL,
01014 INVALID_FLAG
01015 } ;
01016
01017 SETFLAGS ();
01018 }
01019 else if (cstring_equalLit (s, "checks"))
01020 {
01021 flagcode modeflags[] =
01022 {
01023 FLG_EXPORTLOCAL, FLG_IMPTYPE,
01024 FLG_CHECKSTRICTGLOBALIAS,
01025 FLG_CHECKEDGLOBALIAS,
01026 FLG_CHECKMODGLOBALIAS,
01027 FLG_UNCHECKEDGLOBALIAS,
01028 FLG_EXITARG, FLG_PTRNUMCOMPARE,
01029 FLG_BOOLCOMPARE, FLG_MACROUNDEF,
01030 FLG_MUSTMOD, FLG_ALLGLOBALS,
01031 FLG_PREDBOOLOTHERS, FLG_PREDBOOLPTR, FLG_PREDBOOLINT,
01032 FLG_USEALLGLOBS, FLG_MUTREP, FLG_RETALIAS,
01033 FLG_RETEXPOSE, FLG_ASSIGNEXPOSE, FLG_CASTEXPOSE,
01034 FLG_FUNCUNUSED, FLG_GLOBALSIMPMODIFIESNOTHING,
01035 FLG_TYPEUNUSED, FLG_FIELDUNUSED, FLG_PARAMUNUSED, FLG_VARUNUSED,
01036 FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED,
01037 FLG_NOEFFECT, FLG_EXPORTHEADER, FLG_EXPORTHEADERVAR,
01038 FLG_RETVALOTHER, FLG_RETVALBOOL, FLG_RETVALINT,
01039 FLG_SPECUNDEF, FLG_IMPCHECKMODINTERNALS,
01040 FLG_DECLUNDEF, FLG_INCONDEFS, FLG_INCONDEFSLIB,
01041 FLG_MATCHFIELDS,
01042 FLG_MACROPARAMS,
01043 FLG_MACROASSIGN,
01044 FLG_DECLPARAMMATCH,
01045 FLG_FCNDEREF,
01046 FLG_FIRSTCASE,
01047 FLG_SEFPARAMS, FLG_SEFUNSPEC, FLG_MACROSTMT, FLG_MACROPARENS,
01048 FLG_MACROCONSTDECL,
01049 FLG_MACROFCNDECL,
01050 FLG_MACROREDEF,
01051 FLG_INFLOOPS, FLG_INFLOOPSUNCON,
01052 FLG_UNREACHABLE,
01053 FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE,
01054 FLG_EVALORDER, FLG_USEDEF,
01055
01056 FLG_NESTEDEXTERN,
01057
01058
01059
01060 FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
01061 FLG_NULLPASS, FLG_NULLRET,
01062
01063 FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF, FLG_RETSTACK,
01064
01065
01066 FLG_EXPOSETRANS,
01067 FLG_OBSERVERTRANS,
01068 FLG_DEPENDENTTRANS,
01069 FLG_NEWREFTRANS,
01070 FLG_ONLYTRANS,
01071 FLG_OWNEDTRANS,
01072 FLG_FRESHTRANS,
01073 FLG_SHAREDTRANS,
01074 FLG_TEMPTRANS,
01075 FLG_KEPTTRANS,
01076 FLG_REFCOUNTTRANS,
01077 FLG_STATICTRANS,
01078 FLG_UNKNOWNTRANS,
01079 FLG_STATICINITTRANS,
01080 FLG_UNKNOWNINITTRANS,
01081 FLG_KEEPTRANS,
01082 FLG_IMMEDIATETRANS,
01083 FLG_ONLYUNQGLOBALTRANS,
01084 FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
01085 FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE,
01086 FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
01087 FLG_MEMIMPLICIT,
01088 FLG_BRANCHSTATE,
01089 FLG_NULLPOINTERARITH,
01090 FLG_SHADOW, FLG_DEPARRAYS,
01091 FLG_REDECL, FLG_READONLYSTRINGS, FLG_READONLYTRANS,
01092 FLG_LOOPLOOPBREAK, FLG_SWITCHLOOPBREAK, FLG_MODGLOBS,
01093 FLG_CHECKSTRICTGLOBALS, FLG_IMPCHECKEDSPECGLOBALS,
01094 FLG_MACROMATCHNAME, FLG_WARNLINTCOMMENTS,
01095 FLG_INCLUDENEST, FLG_ANSIRESERVED, FLG_CPPNAMES,
01096 FLG_NOPARAMS, FLG_IFEMPTY, FLG_WHILEEMPTY, FLG_REALCOMPARE,
01097 FLG_BOOLOPS, FLG_SHIFTSIGNED,
01098 INVALID_FLAG } ;
01099
01100 SETFLAGS ();
01101 }
01102 else if (cstring_equalLit (s, "strict"))
01103 {
01104 flagcode modeflags[] =
01105 {
01106 FLG_CHECKSTRICTGLOBALIAS,
01107 FLG_CHECKEDGLOBALIAS,
01108 FLG_CHECKMODGLOBALIAS,
01109 FLG_UNCHECKEDGLOBALIAS,
01110 FLG_MODFILESYSTEM,
01111 FLG_MACROMATCHNAME,
01112 FLG_MACROUNDEF, FLG_MUTREP, FLG_MUSTMOD,
01113 FLG_ALLGLOBALS, FLG_IMPTYPE,
01114 FLG_MODNOMODS, FLG_MODGLOBSUNSPEC, FLG_MODSTRICTGLOBSUNSPEC,
01115 FLG_GLOBUNSPEC, FLG_SIZEOFTYPE,
01116 FLG_EXPORTHEADER, FLG_EXPORTHEADERVAR,
01117 FLG_NOPARAMS, FLG_OLDSTYLE, FLG_EXITARG,
01118 FLG_RETSTACK,
01119 FLG_FCNDEREF,
01120 FLG_ONLYUNQGLOBALTRANS,
01121 FLG_GLOBALSIMPMODIFIESNOTHING,
01122 FLG_PREDBOOLOTHERS, FLG_PREDBOOLPTR, FLG_PREDBOOLINT,
01123 FLG_INTERNALGLOBS, FLG_INTERNALGLOBSNOGLOBS,
01124 FLG_USEALLGLOBS, FLG_RETALIAS,
01125 FLG_MODGLOBS, FLG_MODGLOBSUNSPEC, FLG_MODGLOBSUNCHECKED,
01126 FLG_RETEXPOSE, FLG_ASSIGNEXPOSE, FLG_CASTEXPOSE,
01127 FLG_NOEFFECTUNCON, FLG_EVALORDERUNCON,
01128 FLG_FUNCUNUSED,
01129 FLG_EXPORTITER, FLG_EXPORTCONST,
01130 FLG_TYPEUNUSED, FLG_FIELDUNUSED, FLG_PARAMUNUSED, FLG_TOPUNUSED,
01131 FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED,
01132 FLG_VARUNUSED,
01133 FLG_NULLPOINTERARITH, FLG_POINTERARITH,
01134 FLG_PTRNUMCOMPARE,
01135 FLG_BOOLCOMPARE, FLG_NOEFFECT,
01136 FLG_RETVALINT, FLG_RETVALBOOL, FLG_RETVALOTHER,
01137 FLG_ANSIRESERVED, FLG_ANSIRESERVEDLOCAL, FLG_CPPNAMES,
01138 FLG_RETVALBOOL, FLG_RETVALINT, FLG_SPECUNDEF,
01139 FLG_DECLUNDEF, FLG_STRICTOPS, FLG_INCONDEFS,
01140 FLG_INCONDEFSLIB, FLG_MATCHFIELDS, FLG_EXPORTMACRO, FLG_EXPORTVAR,
01141 FLG_EXPORTFCN, FLG_EXPORTTYPE, FLG_EXPORTLOCAL, FLG_MACROPARAMS,
01142 FLG_MACROASSIGN,
01143 FLG_SEFPARAMS, FLG_SEFUNSPEC, FLG_MACROSTMT, FLG_MACROPARENS,
01144 FLG_MACROFCNDECL,
01145 FLG_MACROCONSTDECL,
01146 FLG_MACROREDEF, FLG_MACROEMPTY,
01147 FLG_INFLOOPS, FLG_INFLOOPSUNCON,
01148 FLG_UNREACHABLE,
01149 FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE, FLG_USEDEF,
01150 FLG_EVALORDER,
01151 FLG_MODUNCON, FLG_MODUNCONNOMODS, FLG_MODINTERNALSTRICT,
01152 FLG_MODOBSERVERUNCON,
01153
01154 FLG_NESTEDEXTERN,
01155 FLG_FIRSTCASE,
01156
01157
01158 FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
01159 FLG_NULLPASS, FLG_NULLRET,
01160
01161 FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF,
01162
01163
01164 FLG_EXPOSETRANS,
01165 FLG_OBSERVERTRANS,
01166 FLG_DEPENDENTTRANS,
01167 FLG_NEWREFTRANS,
01168 FLG_ONLYTRANS,
01169 FLG_OWNEDTRANS,
01170 FLG_FRESHTRANS,
01171 FLG_SHAREDTRANS,
01172 FLG_TEMPTRANS,
01173 FLG_KEPTTRANS,
01174 FLG_REFCOUNTTRANS,
01175 FLG_STATICTRANS,
01176 FLG_UNKNOWNTRANS,
01177 FLG_KEEPTRANS,
01178 FLG_IMMEDIATETRANS,
01179 FLG_STATICINITTRANS,
01180 FLG_UNKNOWNINITTRANS,
01181
01182 FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
01183 FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE,
01184 FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
01185 FLG_MEMIMPLICIT,
01186 FLG_BRANCHSTATE,
01187
01188 FLG_DECLPARAMNAME, FLG_DECLPARAMMATCH,
01189
01190 FLG_SHADOW, FLG_DEPARRAYS,
01191 FLG_STRICTDESTROY, FLG_STRICTUSERELEASED, FLG_STRICTBRANCHSTATE,
01192 FLG_REDECL, FLG_READONLYSTRINGS, FLG_READONLYTRANS,
01193 FLG_LOOPLOOPBREAK, FLG_LOOPSWITCHBREAK, FLG_SWITCHLOOPBREAK,
01194 FLG_SWITCHSWITCHBREAK, FLG_LOOPLOOPCONTINUE,
01195 FLG_CHECKSTRICTGLOBALS, FLG_IMPCHECKEDSPECGLOBALS,
01196 FLG_ALLGLOBALS, FLG_IMPCHECKEDSTRICTGLOBALS,
01197 FLG_IMPCHECKEDSTRICTSTATICS,
01198 FLG_IMPCHECKEDSTRICTSPECGLOBALS,
01199 FLG_IMPCHECKMODINTERNALS,
01200 FLG_WARNMISSINGGLOBALS, FLG_WARNMISSINGGLOBALSNOGLOBS,
01201 FLG_WARNLINTCOMMENTS, FLG_ANSIRESERVEDLOCAL,
01202 FLG_INCLUDENEST, FLG_STRINGLITERALLEN,
01203 FLG_NUMSTRUCTFIELDS, FLG_NUMENUMMEMBERS,
01204 FLG_CONTROLNESTDEPTH,
01205 FLG_FORBLOCK, FLG_WHILEBLOCK,
01206 FLG_FOREMPTY, FLG_WHILEEMPTY,
01207 FLG_IFEMPTY, FLG_IFBLOCK,
01208 FLG_ELSEIFCOMPLETE,
01209 FLG_REALCOMPARE, FLG_BOOLOPS,
01210 FLG_SYSTEMDIRERRORS, FLG_UNUSEDSPECIAL,
01211
01212 FLG_SHIFTSIGNED, FLG_BITWISEOPS,
01213 INVALID_FLAG } ;
01214
01215 SETFLAGS ();
01216 }
01217 else
01218 {
01219 llcontbug (message ("context_setMode: bad mode: %s", s));
01220 }
01221 }
01222
01223 bool
01224 context_isSpecialFile (cstring fname)
01225 {
01226 char *ext = filenameExtension (cstring_toCharsSafe (fname));
01227
01228 return (mstring_equal (ext, ".y")
01229 || mstring_equal (ext, ".l")
01230 || cstring_equalLit (fname, "lex.yy.c"));
01231 }
01232
01233 bool
01234 context_isSystemDir (cstring dir)
01235 {
01236 cstring sysDirs = context_exposeString (FLG_SYSTEMDIRS);
01237 char *thisdir = cstring_toCharsSafe (sysDirs);
01238 char *nextdir = strchr (thisdir, SEPCHAR);
01239
01240 if (nextdir != NULL)
01241 {
01242 *nextdir = '\0';
01243 nextdir += 1;
01244 }
01245
01246 while (thisdir != NULL)
01247 {
01248 DPRINTF (("Test: %s / %s", dir, thisdir));
01249
01250 if (cstring_equalCanonicalPrefix (dir, thisdir))
01251 {
01252 if (nextdir != NULL)
01253 {
01254 *(nextdir - 1) = SEPCHAR;
01255 }
01256
01257 return TRUE;
01258 }
01259
01260 if (nextdir != NULL)
01261 {
01262 *(nextdir - 1) = SEPCHAR;
01263 }
01264
01265 if (nextdir != NULL)
01266 {
01267 thisdir = nextdir;
01268 nextdir = strchr (thisdir, SEPCHAR);
01269
01270 if (nextdir != NULL)
01271 {
01272 *nextdir = '\0';
01273 nextdir += 1;
01274 }
01275 }
01276 else
01277 {
01278 break;
01279 }
01280 }
01281
01282 DPRINTF (("Returns FALSE"));
01283 return FALSE;
01284 }
01285
01286 void
01287 context_addFileAccessType (typeId t)
01288 {
01289 cstring base;
01290
01291 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
01292 || gc.kind == CX_UNKNOWNMACRO)
01293 {
01294 gc.acct = typeIdSet_insert (gc.acct, t);
01295 }
01296
01297 gc.facct = typeIdSet_insert (gc.facct, t);
01298
01299 base = fileloc_getBase (g_currentloc);
01300 insertModuleAccess (base, t);
01301 DPRINTF (("Add file access: %s / %s", typeIdSet_unparse (gc.facct),
01302 typeIdSet_unparse (gc.acct)));
01303 }
01304
01305 void
01306 context_removeFileAccessType (typeId t)
01307 {
01308 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
01309 || gc.kind == CX_UNKNOWNMACRO)
01310 {
01311 gc.acct = typeIdSet_removeFresh (gc.acct, t);
01312 }
01313
01314 gc.facct = typeIdSet_removeFresh (gc.facct, t);
01315 gc.nacct = typeIdSet_insert (gc.nacct, t);
01316 }
01317
01318 void context_enterFunctionDecl (void)
01319 {
01320 llassert (gc.kind == CX_GLOBAL);
01321 gc.kind = CX_FCNDECL;
01322 }
01323
01324 void context_exitFunctionDecl (void)
01325 {
01326 gc.kind = CX_GLOBAL;
01327 }
01328
01329 bool context_inFunctionDecl (void)
01330 {
01331 return (gc.kind == CX_FCNDECL);
01332 }
01333
01334 void
01335 context_enterMacro ( uentry e)
01336 {
01337 context_enterFunction (e);
01338 gc.kind = CX_MACROFCN;
01339 }
01340
01341 void
01342 context_enterUnknownMacro ( uentry e)
01343 {
01344 llassert (uentry_isFunction (e));
01345 context_enterFunction (e);
01346 gc.kind = CX_UNKNOWNMACRO;
01347 }
01348
01349 void context_enterAndClause (exprNode e)
01350 {
01351
01352 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
01353 pushClause (ANDCLAUSE);
01354 }
01355
01356 void context_enterOrClause (exprNode e)
01357 {
01358 usymtab_trueBranch (guardSet_invert (exprNode_getGuards (e)));
01359 pushClause (ORCLAUSE);
01360 }
01361
01362 bool context_inDeepLoop (void)
01363 {
01364 bool inLoop = FALSE;
01365
01366 clauseStack_elements (gc.clauses, el)
01367 {
01368 if (clause_isLoop (el))
01369 {
01370 if (inLoop)
01371 {
01372 return TRUE;
01373 }
01374
01375 inLoop = TRUE;
01376 }
01377 } end_clauseStack_elements;
01378
01379 return FALSE;
01380 }
01381
01382 bool context_inDeepSwitch (void)
01383 {
01384 bool inLoop = FALSE;
01385
01386 clauseStack_elements (gc.clauses, el)
01387 {
01388 if (clause_isSwitch (el))
01389 {
01390 if (inLoop)
01391 {
01392 return TRUE;
01393 }
01394
01395 inLoop = TRUE;
01396 }
01397 } end_clauseStack_elements;
01398
01399 return FALSE;
01400 }
01401
01402 bool context_inDeepLoopSwitch (void)
01403 {
01404 bool inLoop = FALSE;
01405
01406 clauseStack_elements (gc.clauses, el)
01407 {
01408 if (clause_isBreakable (el))
01409 {
01410 if (inLoop)
01411 {
01412 return TRUE;
01413 }
01414
01415 inLoop = TRUE;
01416 }
01417 } end_clauseStack_elements;
01418
01419 return FALSE;
01420 }
01421
01422 clause context_breakClause (void)
01423 {
01424 clauseStack_elements (gc.clauses, el)
01425 {
01426 if (clause_isSwitch (el))
01427 {
01428 return el;
01429 }
01430 else if (clause_isLoop (el))
01431 {
01432 return el;
01433 }
01434 else
01435 {
01436 ;
01437 }
01438 } end_clauseStack_elements;
01439
01440 return NOCLAUSE;
01441 }
01442
01443 clause context_nextBreakClause (void)
01444 {
01445 bool hasOne = FALSE;
01446
01447 clauseStack_elements (gc.clauses, el)
01448 {
01449 if (clause_isBreakable (el))
01450 {
01451 if (hasOne)
01452 {
01453 return el;
01454 }
01455 else
01456 {
01457 hasOne = TRUE;
01458 }
01459 }
01460 } end_clauseStack_elements;
01461
01462 return NOCLAUSE;
01463 }
01464
01465 bool context_inConditional (void)
01466 {
01467 clauseStack_elements (gc.clauses, el)
01468 {
01469
01470
01471
01472
01473
01474 if (clause_isBreakable (el) && (el != DOWHILECLAUSE))
01475 {
01476 return TRUE;
01477 }
01478 } end_clauseStack_elements;
01479
01480 return FALSE;
01481 }
01482
01483 void context_exitAndClause (exprNode pred, exprNode tbranch)
01484 {
01485 context_setJustPopped ();
01486
01487 llassert (gc.inclause == ANDCLAUSE);
01488
01489 usymtab_popAndBranch (pred, tbranch);
01490 clauseStack_pop (gc.clauses);
01491 gc.inclause = topClause (gc.clauses);
01492 }
01493
01494 void context_exitOrClause (exprNode pred, exprNode tbranch)
01495 {
01496 context_setJustPopped ();
01497
01498 llassert (gc.inclause == ORCLAUSE);
01499
01500 usymtab_popOrBranch (pred, tbranch);
01501 clauseStack_pop (gc.clauses);
01502 gc.inclause = topClause (gc.clauses);
01503 }
01504
01505 static void context_enterCondClauseAux (clause cl)
01506
01507 {
01508 pushClause (cl);
01509 }
01510
01511 static void context_enterTrueAux (exprNode e, clause cl)
01512
01513 {
01514 usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
01515 pushClause (cl);
01516 }
01517
01518 void context_enterIterClause (void)
01519 {
01520 context_enterTrueAux (exprNode_undefined, ITERCLAUSE);
01521 }
01522
01523 void context_enterDoWhileClause (void)
01524 {
01525 pushClause (DOWHILECLAUSE);
01526 }
01527
01528 void context_enterWhileClause (exprNode e)
01529 {
01530 context_enterTrueAux (e, WHILECLAUSE);
01531 }
01532
01533 void context_enterForClause (exprNode e)
01534 {
01535 context_enterTrueAux (e, FORCLAUSE);
01536 }
01537
01538 void context_enterTrueClause (exprNode e)
01539 {
01540 context_enterTrueAux (e, TRUECLAUSE);
01541 }
01542
01543 void context_enterSwitch (exprNode e)
01544 {
01545
01546 usymtab_switchBranch (e);
01547 context_enterCondClauseAux (SWITCHCLAUSE);
01548 }
01549
01550 void context_exitSwitch (exprNode e, bool allpaths)
01551 {
01552 usymtab_exitSwitch (e, allpaths);
01553
01554 while (clause_isCase (clauseStack_top (gc.clauses)))
01555 {
01556 clauseStack_pop (gc.clauses);
01557 }
01558
01559 context_exitClauseSimp ();
01560 }
01561
01562 void context_enterCaseClause (exprNode e)
01563 {
01564 bool branch = FALSE;
01565
01566 DPRINTF (("Enter case clause!"));
01567
01568 branch = usymtab_newCase (exprNode_undefined, e);
01569
01570 if (branch)
01571 {
01572 context_enterCondClauseAux (CASECLAUSE);
01573 }
01574 }
01575
01576 static void context_enterFalseClauseAux (exprNode e, clause cl)
01577
01578 {
01579 usymtab_altBranch (guardSet_invert (exprNode_getGuards (e)));
01580 gc.inclause = cl;
01581 clauseStack_switchTop (gc.clauses, cl);
01582 }
01583
01584 void context_enterFalseClause (exprNode e)
01585 {
01586
01587 context_enterFalseClauseAux (e, FALSECLAUSE);
01588 }
01589
01590 void
01591 context_enterConstantMacro ( uentry e)
01592 {
01593 gc.kind = CX_MACROCONST;
01594 gc.cont.fcn = e;
01595 gc.showfunction = context_getFlag (FLG_SHOWFUNC);
01596
01597 gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)),
01598 gc.nacct);
01599
01600
01601 usymtab_enterScope ();
01602 sRef_enterFunctionScope ();
01603
01604 gc.globs = globSet_undefined;
01605 globSet_clear (gc.globs_used);
01606 gc.mods = sRefSet_undefined;
01607 }
01608
01609 uentry context_getHeader (void)
01610 {
01611 if (!(context_inFunctionLike () || (gc.kind == CX_MACROCONST)))
01612 {
01613 llfatalbug (message ("context_getHeader: bad call: %q",
01614 context_unparse ()));
01615 }
01616
01617 return (gc.cont.fcn);
01618 }
01619
01620 void
01621 context_setFunctionDefined (fileloc loc)
01622 {
01623 switch (gc.kind)
01624 {
01625 case CX_UNKNOWNMACRO:
01626 case CX_FUNCTION:
01627 case CX_MACROFCN:
01628 uentry_setFunctionDefined (gc.cont.fcn, loc);
01629 break;
01630 default:
01631
01632 break;
01633 }
01634 }
01635
01636 void
01637 context_enterFunction ( uentry e)
01638 {
01639 gc.kind = CX_FUNCTION;
01640 gc.cont.fcn = e;
01641
01642 if (uentry_hasAccessType (e))
01643 {
01644 gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)),
01645 gc.nacct);
01646 }
01647 else
01648 {
01649 gc.acct = gc.facct;
01650 }
01651
01652 DPRINTF (("Enter function: %s / %s", uentry_unparse (e),
01653 typeIdSet_unparse (gc.acct)));
01654
01655 gc.showfunction = context_getFlag (FLG_SHOWFUNC);
01656
01657 gc.globs = uentry_getGlobs (e);
01658 globSet_clear (gc.globs_used);
01659 gc.mods = uentry_getMods (e);
01660
01661 usymtab_enterFunctionScope (e);
01662 sRef_enterFunctionScope ();
01663 }
01664
01665 static bool context_checkStrictGlobals (void)
01666 {
01667 return (context_getFlag (FLG_CHECKSTRICTGLOBALS));
01668 }
01669
01670 static bool context_hasGlobs (void)
01671 {
01672 if (context_inFunctionLike ())
01673 {
01674 return (uentry_hasGlobs (gc.cont.fcn));
01675 }
01676 else
01677 {
01678 return (FALSE);
01679 }
01680 }
01681
01682 static bool context_checkCheckedGlobals (void)
01683 {
01684 return (context_getFlag (FLG_GLOBALS)
01685 && (context_getFlag (FLG_GLOBUNSPEC)
01686 || context_hasGlobs ()));
01687 }
01688
01689 static bool context_checkUnknownGlobals (void)
01690 {
01691
01692
01693 return (context_getFlag (FLG_ALLGLOBALS)
01694 && (context_getFlag (FLG_GLOBUNSPEC)
01695 || context_hasGlobs ()));
01696 }
01697
01698 static bool context_checkUncheckedGlobals (void)
01699 {
01700 return (FALSE);
01701 }
01702
01703 bool
01704 context_checkExport (uentry e)
01705 {
01706 if (!gc.anyExports) return FALSE;
01707
01708 if (uentry_isFunction (e)
01709 || (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))))
01710 {
01711 return context_maybeSet (FLG_EXPORTFCN);
01712 }
01713 else if (uentry_isExpandedMacro (e))
01714 {
01715 return context_maybeSet (FLG_EXPORTMACRO);
01716 }
01717 else if (uentry_isVariable (e))
01718 {
01719 return context_maybeSet (FLG_EXPORTVAR);
01720 }
01721 else if (uentry_isEitherConstant (e))
01722 {
01723 return context_maybeSet (FLG_EXPORTCONST);
01724 }
01725 else if (uentry_isIter (e) || uentry_isEndIter (e))
01726 {
01727 return context_maybeSet (FLG_EXPORTITER);
01728 }
01729 else if (uentry_isDatatype (e))
01730 {
01731 return context_maybeSet (FLG_EXPORTTYPE);
01732 }
01733 else
01734 {
01735 BADEXIT;
01736 }
01737 }
01738
01739 bool
01740 context_checkGlobUse (uentry glob)
01741 {
01742
01743 if (uentry_isCheckedStrict (glob))
01744 {
01745 return context_checkStrictGlobals ();
01746 }
01747 else if (uentry_isChecked (glob))
01748 {
01749 return context_checkCheckedGlobals ();
01750 }
01751 else if (uentry_isCheckedUnknown (glob) || uentry_isCheckMod (glob))
01752 {
01753 return context_checkUnknownGlobals ();
01754 }
01755 else
01756 {
01757 llassert (uentry_isUnchecked (glob));
01758
01759 return context_checkUncheckedGlobals ();
01760 }
01761 }
01762
01763 bool
01764 context_checkAliasGlob (uentry glob)
01765 {
01766 if (uentry_isCheckedStrict (glob))
01767 {
01768 return gc.flags[FLG_CHECKSTRICTGLOBALIAS];
01769 }
01770 else if (uentry_isChecked (glob))
01771 {
01772 return gc.flags[FLG_CHECKEDGLOBALIAS];
01773 }
01774 else if (uentry_isCheckMod (glob))
01775 {
01776 return gc.flags[FLG_CHECKMODGLOBALIAS];
01777 }
01778 else
01779 {
01780 llassert (uentry_isUnchecked (glob) || uentry_isCheckedUnknown (glob));
01781
01782 return gc.flags[FLG_UNCHECKEDGLOBALIAS];
01783 }
01784 }
01785
01786 bool context_checkInternalUse (void)
01787 {
01788 if (context_hasGlobs ())
01789 {
01790 return (gc.flags[FLG_INTERNALGLOBS]);
01791 }
01792 else
01793 {
01794 return (gc.flags[FLG_INTERNALGLOBSNOGLOBS]);
01795 }
01796 }
01797
01798 bool
01799 context_checkGlobMod (sRef el)
01800 {
01801 uentry ue = sRef_getUentry (el);
01802
01803
01804
01805 if (uentry_isCheckedModify (ue)
01806 || (!uentry_isUnchecked (ue) && (gc.flags[FLG_ALLGLOBALS])))
01807 {
01808 if (context_hasMods ())
01809 {
01810 return (gc.flags[FLG_MODGLOBS]);
01811 }
01812 else
01813 {
01814 if (uentry_isCheckedStrict (ue))
01815 {
01816 return (gc.flags[FLG_MODGLOBSUNSPEC]);
01817 }
01818 else
01819 {
01820 return (gc.flags[FLG_MODSTRICTGLOBSUNSPEC]);
01821 }
01822 }
01823 }
01824 else
01825 {
01826 if (context_hasMods ())
01827 {
01828 return (gc.flags[FLG_MODGLOBSUNCHECKED]);
01829 }
01830 else
01831 {
01832 return FALSE;
01833 }
01834 }
01835 }
01836
01837 void
01838 context_usedGlobal (sRef el)
01839 {
01840 if (!globSet_member (gc.globs_used, el))
01841 {
01842
01843
01844
01845
01846
01847
01848 sRef_clearDerived (el);
01849 gc.globs_used = globSet_insert (gc.globs_used, el);
01850 }
01851 }
01852
01853 sRefSet
01854 context_modList (void)
01855 {
01856 return gc.mods;
01857 }
01858
01859 bool
01860 context_globAccess (sRef s)
01861 {
01862 llassert (sRef_isGlobal (s) || sRef_isKindSpecial (s));
01863 return (globSet_member (gc.globs, s));
01864 }
01865
01866 bool
01867 context_hasAccess (typeId t)
01868 {
01869 if (context_inFunctionLike ())
01870 {
01871 return (typeIdSet_member (gc.acct, t));
01872 }
01873 else
01874 {
01875 return (context_hasFileAccess (t));
01876 }
01877 }
01878
01879 bool
01880 context_hasFileAccess (typeId t)
01881 {
01882 return (typeIdSet_member (gc.facct, t));
01883 }
01884
01885 cstring
01886 context_unparseAccess (void)
01887 {
01888 return (message ("%q / %q", typeIdSet_unparse (gc.acct),
01889 typeIdSet_unparse (gc.facct)));
01890 }
01891
01892 cstring
01893 context_unparseClauses (void)
01894 {
01895 return (clauseStack_unparse (gc.clauses));
01896 }
01897
01898 bool
01899 context_couldHaveAccess (typeId t)
01900 {
01901 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN || gc.kind == CX_UNKNOWNMACRO)
01902 {
01903 return (typeIdSet_member (gc.acct, t));
01904 }
01905 else
01906 {
01907 return (typeIdSet_member (gc.facct, t));
01908 }
01909 }
01910
01911 ctype
01912 context_getRetType (void)
01913 {
01914 ctype f = ctype_undefined;
01915
01916 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN)
01917 {
01918 f = uentry_getType (gc.cont.fcn);
01919 }
01920 else if (gc.kind == CX_UNKNOWNMACRO)
01921 {
01922 return ctype_unknown;
01923 }
01924 else
01925 {
01926 llcontbuglit ("context_getRetType: not in a function context");
01927 return ctype_unknown;
01928 }
01929
01930 if (!ctype_isFunction (f))
01931 {
01932 if (ctype_isKnown (f))
01933 {
01934 llbuglit ("context_getRetType: not a function");
01935 }
01936
01937 return ctype_unknown;
01938 }
01939 return (ctype_returnValue (f));
01940 }
01941
01942 bool
01943 context_hasMods (void)
01944 {
01945 if (context_inFunctionLike ())
01946 {
01947 return (uentry_hasMods (gc.cont.fcn));
01948 }
01949 else
01950 {
01951 return FALSE;
01952 }
01953 }
01954
01955 void
01956 context_exitAllClauses (void)
01957 {
01958
01959 while (!clauseStack_isEmpty (gc.clauses))
01960 {
01961 clause el = clauseStack_top (gc.clauses);
01962
01963 gc.inclause = el;
01964
01965 if (clause_isNone (el))
01966 {
01967 usymtab_quietExitScope (g_currentloc);
01968 clauseStack_pop (gc.clauses);
01969 }
01970 else
01971 {
01972 context_exitClausePlain ();
01973 }
01974 }
01975
01976 clauseStack_clear (gc.clauses);
01977
01978
01979 gc.inclause = NOCLAUSE;
01980 }
01981
01982 static
01983 void context_exitClauseSimp (void)
01984 {
01985
01986 context_setJustPopped ();
01987 clauseStack_pop (gc.clauses);
01988 gc.inclause = topClause (gc.clauses);
01989 }
01990
01991 static
01992 void context_exitCaseClause (void)
01993 {
01994 context_setJustPopped ();
01995 usymtab_popCaseBranch ();
01996 clauseStack_pop (gc.clauses);
01997 gc.inclause = topClause (gc.clauses);
01998 }
01999
02000 static
02001 void context_exitClauseAux (exprNode pred, exprNode tbranch)
02002 {
02003 context_setJustPopped ();
02004 usymtab_popTrueBranch (pred, tbranch, gc.inclause);
02005 clauseStack_pop (gc.clauses);
02006 gc.inclause = topClause (gc.clauses);
02007 }
02008
02009 void context_exitTrueClause (exprNode pred, exprNode tbranch)
02010 {
02011 if (gc.inclause != TRUECLAUSE)
02012 {
02013 llparseerror (cstring_makeLiteral
02014 ("Likely parse error. Conditional clauses are inconsistent."));
02015 return;
02016 }
02017
02018
02019 context_setJustPopped ();
02020
02021 usymtab_popTrueBranch (pred, tbranch, TRUECLAUSE);
02022 clauseStack_pop (gc.clauses);
02023 gc.inclause = topClause (gc.clauses);
02024
02025 }
02026
02027 void context_exitIterClause (exprNode body)
02028 {
02029 llassert (gc.inclause == ITERCLAUSE);
02030
02031 context_setJustPopped ();
02032
02033 if (context_getFlag (FLG_LOOPEXEC))
02034 {
02035 usymtab_popTrueExecBranch (exprNode_undefined, body, ITERCLAUSE);
02036 }
02037 else
02038 {
02039 usymtab_popTrueBranch (exprNode_undefined, body, ITERCLAUSE);
02040 }
02041
02042 clauseStack_pop (gc.clauses);
02043 gc.inclause = topClause (gc.clauses);
02044 }
02045
02046 static void context_popCase (void) {
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062 DPRINTF (("Popping case clause: %s",
02063 clauseStack_unparse (gc.clauses)));
02064
02065 if (gc.inclause == CASECLAUSE) {
02066 context_exitCaseClause ();
02067 }
02068 }
02069
02070 void context_exitWhileClause (exprNode pred, exprNode body)
02071 {
02072 guardSet invGuards = guardSet_invert (exprNode_getGuards (pred));
02073
02074 context_popCase ();
02075
02076 if (gc.inclause != WHILECLAUSE) {
02077 DPRINTF (("Clause: %s / %s", clause_unparse (gc.inclause),
02078 clauseStack_unparse (gc.clauses)));
02079 }
02080
02081 llassert (gc.inclause == WHILECLAUSE);
02082
02083 context_setJustPopped ();
02084
02085
02086
02087
02088
02089
02090 if (context_getFlag (FLG_LOOPEXEC))
02091 {
02092 usymtab_popTrueExecBranch (pred, body, WHILECLAUSE);
02093 }
02094 else
02095 {
02096 usymtab_popTrueBranch (pred, body, WHILECLAUSE);
02097 }
02098
02099
02100 usymtab_addGuards (invGuards);
02101 guardSet_free (invGuards);
02102
02103 clauseStack_pop (gc.clauses);
02104 gc.inclause = topClause (gc.clauses);
02105 }
02106
02107 void context_exitDoWhileClause (exprNode pred)
02108 {
02109 guardSet invGuards = guardSet_invert (exprNode_getGuards (pred));
02110
02111 if (gc.inclause == CASECLAUSE) {
02112
02113 clauseStack_pop (gc.clauses);
02114 gc.inclause = topClause (gc.clauses);
02115 }
02116
02117 llassert (gc.inclause == DOWHILECLAUSE);
02118
02119 context_setJustPopped ();
02120
02121
02122 usymtab_addGuards (invGuards);
02123 guardSet_free (invGuards);
02124
02125 clauseStack_pop (gc.clauses);
02126 gc.inclause = topClause (gc.clauses);
02127 }
02128
02129 void context_exitForClause (exprNode forPred, exprNode body)
02130 {
02131 guardSet invGuards = guardSet_invert (exprNode_getForGuards (forPred));
02132
02133 llassert (gc.inclause == FORCLAUSE);
02134 context_setJustPopped ();
02135
02136
02137
02138
02139
02140 if (context_getFlag (FLG_LOOPEXEC))
02141 {
02142 usymtab_popTrueExecBranch (forPred, body, FORCLAUSE);
02143 }
02144 else
02145 {
02146 usymtab_popTrueBranch (forPred, body, FORCLAUSE);
02147 }
02148
02149 usymtab_addGuards (invGuards);
02150 guardSet_free (invGuards);
02151 clauseStack_pop (gc.clauses);
02152 gc.inclause = topClause (gc.clauses);
02153 }
02154
02155 static void context_exitClausePlain (void)
02156 {
02157 llassert (gc.inclause != NOCLAUSE);
02158
02159 if (gc.inclause == FALSECLAUSE)
02160 {
02161 context_exitClause (exprNode_undefined, exprNode_undefined, exprNode_undefined);
02162 }
02163 else
02164 {
02165 context_exitClauseAux (exprNode_undefined, exprNode_undefined);
02166 }
02167
02168 }
02169
02170 void context_exitClause (exprNode pred, exprNode tbranch, exprNode fbranch)
02171 {
02172
02173 context_setJustPopped ();
02174
02175 if (gc.inclause == FALSECLAUSE)
02176 {
02177 usymtab_popBranches (pred, tbranch, fbranch, FALSE, FALSECLAUSE);
02178
02179 llassert (clauseStack_top (gc.clauses) == FALSECLAUSE);
02180
02181 clauseStack_pop (gc.clauses);
02182 gc.inclause = topClause (gc.clauses);
02183 }
02184 else
02185 {
02186 context_exitTrueClause (pred, tbranch);
02187 }
02188 }
02189
02190 void
02191 context_returnFunction (void)
02192 {
02193 usymtab_checkFinalScope (TRUE);
02194 }
02195
02196 void
02197 context_exitFunction (void)
02198 {
02199 if (!context_inFunction () && !context_inMacroConstant ()
02200 && !context_inMacroUnknown ()
02201 && !context_inIterDef () && !context_inIterEnd ())
02202 {
02203
02204
02205
02206 }
02207 else
02208 {
02209 if (context_inMacro () && usymtab_inFunctionScope ())
02210 {
02211 usymtab_exitScope (exprNode_undefined);
02212 }
02213
02214 if (uentry_hasGlobs (gc.cont.fcn))
02215 {
02216 exprChecks_checkUsedGlobs (gc.globs, gc.globs_used);
02217 }
02218
02219
02220 if (uentry_hasMods (gc.cont.fcn))
02221 {
02222 if (context_getFlag (FLG_MUSTMOD))
02223 {
02224 exprNode_checkAllMods (gc.mods, gc.cont.fcn);
02225 }
02226 }
02227
02228
02229
02230
02231
02232
02233
02234 usymtab_exitScope (exprNode_undefined);
02235 sRef_exitFunctionScope ();
02236
02237 gc.showfunction = FALSE;
02238 gc.kind = CX_GLOBAL;
02239 gc.cont.glob = TRUE;
02240 gc.acct = gc.facct;
02241 gc.globs = globSet_new ();
02242 globSet_clear (gc.globs_used);
02243 gc.mods = sRefSet_new ();
02244 }
02245
02246 llassert (clauseStack_isEmpty (gc.clauses));
02247 llassert (gc.inclause == NOCLAUSE);
02248 }
02249
02250 void
02251 context_quietExitFunction (void)
02252 {
02253 while (gc.kind == CX_INNER)
02254 {
02255 context_exitInnerPlain ();
02256 }
02257
02258 if (!context_inFunction () && !context_inMacroConstant () && !context_inMacroUnknown ()
02259 && !context_inIterDef () && !context_inIterEnd ())
02260 {
02261 }
02262 else
02263 {
02264 usymtab_quietExitScope (g_currentloc);
02265
02266 gc.showfunction = FALSE;
02267 gc.kind = CX_GLOBAL;
02268 gc.cont.glob = TRUE;
02269 gc.acct = gc.facct;
02270 gc.globs = globSet_new ();
02271 globSet_clear (gc.globs_used);
02272 gc.mods = sRefSet_new ();
02273
02274 sRef_exitFunctionScope ();
02275 }
02276 }
02277
02278 uentryList
02279 context_getParams (void)
02280 {
02281 if (context_inFunctionLike ())
02282 {
02283 return (uentry_getParams (gc.cont.fcn));
02284 }
02285 else
02286 {
02287 llcontbug (message ("context_getParams: not in function: %q", context_unparse ()));
02288 return uentryList_undefined;
02289 }
02290 }
02291
02292 globSet
02293 context_getUsedGlobs (void)
02294 {
02295 llassert (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
02296 || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
02297
02298 return (gc.globs_used);
02299 }
02300
02301 cstring
02302 context_moduleName ()
02303 {
02304 return (fileloc_getBase (g_currentloc));
02305 }
02306
02307 globSet
02308 context_getGlobs (void)
02309 {
02310 llassert (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
02311 || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
02312
02313 return (gc.globs);
02314 }
02315
02316 void
02317 context_addBoolAccess (void)
02318 {
02319 cstring bname = context_getString (FLG_BOOLTYPE);
02320 typeIdSet boolt = typeIdSet_single (usymtab_getTypeId (bname));
02321
02322 addModuleAccess (cstring_copy (bname), boolt);
02323
02324
02325 addModuleAccess (cstring_makeLiteral ("types"), boolt);
02326 }
02327
02328 # if 0
02329 bool
02330 context_canAccessBool (void)
02331 {
02332 return TRUE;
02333 }
02334 # endif
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354 ctype
02355 context_boolImplementationType () {
02356
02357 return ctype_int;
02358 }
02359
02360 bool
02361 context_canAccessBool (void)
02362 {
02363 static typeId boolType = typeId_invalid;
02364
02365 if (typeId_isInvalid (boolType))
02366 {
02367 boolType = usymtab_getTypeId (context_getBoolName ());
02368 }
02369
02370 if (!typeId_isInvalid (boolType))
02371 {
02372 return context_hasAccess (boolType);
02373 }
02374 else
02375 {
02376 ;
02377 }
02378
02379 return FALSE;
02380 }
02381
02382 void
02383 context_setMessageAnnote ( cstring s)
02384 {
02385 llassert (cstring_isUndefined (gc.msgAnnote));
02386 gc.msgAnnote = s;
02387 }
02388
02389 bool
02390 context_hasMessageAnnote (void)
02391 {
02392 return (cstring_isDefined (gc.msgAnnote));
02393 }
02394
02395 void
02396 context_clearMessageAnnote (void)
02397 {
02398 if (cstring_isDefined (gc.msgAnnote))
02399 {
02400 cstring_free (gc.msgAnnote);
02401 gc.msgAnnote = cstring_undefined;
02402 }
02403 }
02404
02405 cstring
02406 context_getMessageAnnote (void)
02407 {
02408 cstring st = gc.msgAnnote;
02409
02410 gc.msgAnnote = cstring_undefined;
02411 return st;
02412 }
02413
02414 void
02415 context_setAliasAnnote ( sRef s, sRef t)
02416 {
02417 llassert (sRef_isInvalid (gc.aliasAnnote));
02418 llassert (!sRef_sameName (s, t));
02419 gc.aliasAnnote = s;
02420 gc.aliasAnnoteAls = t;
02421 }
02422
02423 bool
02424 context_hasAliasAnnote (void)
02425 {
02426 return (sRef_isValid (gc.aliasAnnote));
02427 }
02428
02429 void
02430 context_clearAliasAnnote (void)
02431 {
02432 gc.aliasAnnote = sRef_undefined;
02433 }
02434
02435 cstring
02436 context_getAliasAnnote (void)
02437 {
02438 sRef ret = gc.aliasAnnote;
02439 sRef als = gc.aliasAnnoteAls;
02440
02441 llassert (sRef_isValid (ret) && sRef_isValid (als));
02442
02443 gc.aliasAnnote = sRef_undefined;
02444 return (message ("%q aliases %q", sRef_unparse (als), sRef_unparse (ret)));
02445 }
02446
02447 void
02448 context_recordFileModifies (sRefSet mods)
02449 {
02450 gc.modrecs = sRefSetList_add (gc.modrecs, mods);
02451 }
02452
02453 void
02454 context_recordFileGlobals (globSet mods)
02455 {
02456 context_recordFileModifies (mods);
02457 }
02458
02459 void
02460 context_setCommentMarkerChar (char c)
02461 {
02462 llassert (c != '\0');
02463
02464 context_setValue (FLG_COMMENTCHAR, (int) c);
02465 }
02466
02467 char
02468 context_getCommentMarkerChar (void)
02469 {
02470 return ((char) context_getValue (FLG_COMMENTCHAR));
02471 }
02472
02473 static void
02474 context_setValue (flagcode flag, int val)
02475 {
02476 int index = flagcode_valueIndex (flag);
02477
02478 llassert (index >= 0 && index <= NUMVALUEFLAGS);
02479
02480 if (val <= 0)
02481 {
02482 switch (flag)
02483 {
02484 case FLG_INCLUDENEST:
02485 case FLG_CONTROLNESTDEPTH:
02486 case FLG_STRINGLITERALLEN:
02487 case FLG_NUMSTRUCTFIELDS:
02488 case FLG_NUMENUMMEMBERS:
02489 case FLG_LINELEN:
02490 {
02491 cstring warn = message ("Value for %s must be a positive "
02492 "number (given %d)",
02493 flagcode_unparse (flag), val);
02494
02495 flagWarning (warn);
02496 cstring_free (warn);
02497 val = MINLINELEN;
02498 }
02499 return;
02500 default:
02501 break;
02502 }
02503 }
02504
02505 if (flag == FLG_LINELEN && val < MINLINELEN)
02506 {
02507 cstring warn = message ("Value for %s must be at least %d (given %d)",
02508 flagcode_unparse (flag),
02509 MINLINELEN, val);
02510 flagWarning (warn);
02511 cstring_free (warn);
02512 val = MINLINELEN;
02513 }
02514
02515 gc.values[index] = val;
02516 }
02517
02518 void
02519 context_setValueAndFlag (flagcode flag, int val)
02520 {
02521 gc.flags[flag] = TRUE;
02522 context_setValue (flag, val);
02523 }
02524
02525 int
02526 context_getValue (flagcode flag)
02527 {
02528 int index = flagcode_valueIndex (flag);
02529
02530 llassert (index >= 0 && index <= NUMVALUEFLAGS);
02531 return (gc.values[index]);
02532 }
02533
02534 int
02535 context_getCounter (flagcode flag)
02536 {
02537 int index = flagcode_valueIndex (flag);
02538
02539 llassert (index >= 0 && index <= NUMVALUEFLAGS);
02540 return (gc.counters[index]);
02541 }
02542
02543 void
02544 context_incCounter (flagcode flag)
02545 {
02546 int index = flagcode_valueIndex (flag);
02547
02548 llassert (index >= 0 && index <= NUMVALUEFLAGS);
02549
02550 gc.counters[index]++;
02551 }
02552
02553 void
02554 context_decCounter (flagcode flag)
02555 {
02556 int index = flagcode_valueIndex (flag);
02557
02558 llassert (index >= 0 && index <= NUMVALUEFLAGS);
02559 gc.counters[index]--;
02560 }
02561
02562 bool context_showFunction (void)
02563 {
02564 return (gc.showfunction);
02565 }
02566
02567 void
02568 context_setString (flagcode flag, cstring val)
02569 {
02570 int index = flagcode_stringIndex (flag);
02571
02572 llassert (index >= 0 && index <= NUMSTRINGFLAGS);
02573
02574 if (flag == FLG_SYSTEMDIRS)
02575 {
02576 llassert (cstring_isDefined (val));
02577
02578 if (cstring_firstChar (val) == '\"')
02579 {
02580 cstring oval = val;
02581 cstring tval = cstring_copy (cstring_suffix (val, 1));
02582
02583 if (cstring_lastChar (tval) != '\"')
02584 {
02585 int n = cstring_length (tval) - 1;
02586
02587 while (isspace ((int) cstring_getChar (tval, n)))
02588 {
02589 n--;
02590 }
02591
02592 if (cstring_getChar (tval, n) != '\"')
02593 {
02594 cstring msg = message ("Setting -systemdirs to string with unmatching quotes: %s", val);
02595 flagWarning (msg);
02596 cstring_free (msg);
02597 }
02598 else
02599 {
02600 cstring otval = tval;
02601 tval = cstring_prefix (tval, n);
02602 cstring_free (otval);
02603 }
02604 }
02605
02606 val = cstring_copy (cstring_clip (tval, cstring_length (tval) - 1));
02607 DPRINTF (("val = %s", val));
02608 cstring_free (tval);
02609 cstring_free (oval);
02610 }
02611 }
02612
02613 if (flag == FLG_TMPDIR)
02614 {
02615 llassert (cstring_isDefined (val));
02616
02617 if (cstring_length (val) == 0)
02618 {
02619 cstring_free (val);
02620 val = message (".%s", cstring_makeLiteralTemp (CONNECTSTR));
02621 }
02622 else if (cstring_lastChar (val) != CONNECTCHAR)
02623 {
02624 val = cstring_appendChar (val, CONNECTCHAR);
02625 }
02626 else
02627 {
02628 ;
02629 }
02630 }
02631
02632 if (cstring_length (val) >= 1
02633 && cstring_firstChar (val) == '"')
02634 {
02635 cstring s = message
02636 ("setting %s to string beginning with \". You probably "
02637 "don't meant to have the \"'s.",
02638 flagcode_unparse (flag));
02639
02640 flagWarning (s);
02641 cstring_free (s);
02642 }
02643
02644 if (flag == FLG_BOOLTYPE)
02645 {
02646
02647 }
02648
02649 gc.strings[index] = val;
02650 }
02651
02652 static cstring
02653 context_exposeString (flagcode flag)
02654 {
02655 int index = flagcode_stringIndex (flag);
02656
02657 llassert (index >= 0 && index <= NUMSTRINGFLAGS);
02658 return (gc.strings[index]);
02659 }
02660
02661 cstring
02662 context_getString (flagcode flag)
02663 {
02664 return (context_exposeString (flag));
02665 }
02666
02667 void
02668 context_resetErrors (void)
02669 {
02670 gc.numerrors = 0;
02671 }
02672
02673 void context_initMod (void)
02674
02675 {
02676 gc.kind = CX_GLOBAL;
02677 gc.instandardlib = FALSE;
02678 gc.numerrors = 0;
02679 gc.neednl = FALSE;
02680 gc.linesprocessed = 0;
02681 gc.speclinesprocessed = 0;
02682 gc.insuppressregion = FALSE;
02683 gc.macroMissingParams = FALSE;
02684 gc.preprocessing = FALSE;
02685 gc.incommandline = FALSE;
02686 gc.mc = macrocache_create ();
02687 gc.nmods = 0;
02688 gc.maxmods = DEFAULTMAXMODS;
02689 gc.moduleaccess = (maccesst *)
02690 dmalloc (sizeof (*gc.moduleaccess) * (gc.maxmods));
02691
02692 gc.library = FLG_ANSILIB;
02693
02694 gc.locstack = filelocStack_new ();
02695 gc.modrecs = sRefSetList_undefined;
02696 gc.anyExports = FALSE;
02697
02698 gc.ftab = fileTable_create ();
02699 gc.msgLog = messageLog_new ();
02700 gc.inimport = FALSE;
02701 gc.inDerivedFile = FALSE;
02702 gc.inheader = FALSE;
02703 gc.markers = flagMarkerList_new ();
02704 gc.cont.glob = TRUE;
02705 gc.showfunction = FALSE;
02706 gc.msgAnnote = cstring_undefined;
02707 gc.aliasAnnote = sRef_undefined;
02708 gc.aliasAnnoteAls = sRef_undefined;
02709 gc.boolType = ctype_bool;
02710 gc.mods = sRefSet_new ();
02711
02712 gc.saveloc = fileloc_undefined;
02713
02714 gc.inmacrocache = FALSE;
02715 gc.inclause = NOCLAUSE;
02716 gc.clauses = clauseStack_new ();
02717 gc.globs = globSet_new ();
02718 gc.nacct = typeIdSet_emptySet ();
02719 gc.acct = typeIdSet_emptySet ();
02720 gc.facct = typeIdSet_emptySet ();
02721 gc.savedFlags = FALSE;
02722 gc.pushloc = fileloc_undefined;
02723 gc.protectVars = FALSE;
02724 gc.justpopped = FALSE;
02725 gc.isNullGuarded = NO;
02726 gc.globs_used = globSet_undefined;
02727
02728 allFlagCodes (code)
02729 {
02730 gc.setGlobally[code] = FALSE;
02731 gc.setLocally[code] = FALSE;
02732 } end_allFlagCodes ;
02733
02734 usymtab_initMod ();
02735
02736 context_resetAllFlags ();
02737 conext_resetAllCounters ();
02738 context_setMode (DEFAULT_MODE);
02739 }
02740
02741 ctype
02742 context_typeofZero (void)
02743 {
02744 ctype ct = ctype_int;
02745
02746 if (context_getFlag (FLG_ZEROPTR))
02747 {
02748 ct = ctype_makeConj (ct, ctype_voidPointer);
02749 }
02750
02751 if (context_getFlag (FLG_ZEROBOOL)) {
02752 ct = ctype_makeConj (ct, ctype_bool);
02753 }
02754
02755 return ct;
02756 }
02757
02758 ctype
02759 context_typeofOne (void)
02760 {
02761 ctype ct = ctype_int;
02762
02763
02764
02765
02766
02767
02768
02769
02770 return (ct);
02771 }
02772
02773 cstring
02774 context_unparse (void)
02775 {
02776 cstring s;
02777
02778 switch (gc.kind)
02779 {
02780 case CX_LCL:
02781 s = message ("LCL File: %q", fileloc_unparse (g_currentloc));
02782 break;
02783 case CX_LCLLIB:
02784 s = message ("LCL Lib File: %q", fileloc_unparse (g_currentloc));
02785 break;
02786 case CX_GLOBAL:
02787 s = message ("Global Context:%q", fileloc_unparse (g_currentloc));
02788 break;
02789 case CX_INNER:
02790 s = message ("Inner Context:%q", fileloc_unparse (g_currentloc));
02791 break;
02792 case CX_FUNCTION:
02793 s = message ("Function %q :%q \n\taccess %q\n\tmodifies %q",
02794 uentry_unparse (gc.cont.fcn),
02795 fileloc_unparse (g_currentloc),
02796 typeIdSet_unparse (gc.acct),
02797 sRefSet_unparse (gc.mods));
02798 break;
02799 case CX_MACROFCN:
02800 s = message ("Function Macro %q", uentry_unparse (gc.cont.fcn));
02801 break;
02802 case CX_UNKNOWNMACRO:
02803 s = message ("Forward Specified Macro %q", uentry_unparse (gc.cont.fcn));
02804 break;
02805 case CX_MACROCONST:
02806 s = message ("Constant Macro %q", uentry_unparse (gc.cont.fcn));
02807 break;
02808 case CX_ITERDEF:
02809 s = message ("Iter definition %q", uentry_unparse (gc.cont.fcn));
02810 break;
02811 case CX_ITEREND:
02812 s = message ("Iter end %q", uentry_unparse (gc.cont.fcn));
02813 break;
02814 default:
02815 s = message ("Un-unparseable context: %d", (int) gc.kind);
02816 break;
02817 }
02818
02819 s = message ("%q\naccess: %q", s, context_unparseAccess ());
02820 return (s);
02821 }
02822
02823 extern ctype
02824 context_currentFunctionType (void)
02825 {
02826 if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN)
02827 {
02828 return (uentry_getType (gc.cont.fcn));
02829 }
02830 else if (gc.kind == CX_INNER)
02831 {
02832 llcontbuglit ("context_currentFunctionType: inner context");
02833 do { context_exitInnerPlain (); } while (gc.kind == CX_INNER);
02834 return (context_currentFunctionType ());
02835 }
02836 else
02837 {
02838 llcontbuglit ("context_currentFunctionType: not in function");
02839 return (ctype_undefined);
02840 }
02841 }
02842
02843 void
02844 context_enterInnerContext (void)
02845 {
02846 if (gc.kind == CX_GLOBAL)
02847 {
02848 gc.kind = CX_INNER;
02849 gc.cont.cdepth = 1;
02850 }
02851 else if (gc.kind == CX_INNER)
02852 {
02853 gc.cont.cdepth++;
02854 }
02855 else
02856 {
02857 ;
02858 }
02859
02860
02861 usymtab_enterScope ();
02862 pushClause (NOCLAUSE);
02863 }
02864
02865 void
02866 context_exitInnerPlain (void)
02867 {
02868 context_exitInner (exprNode_undefined);
02869 }
02870
02871 void
02872 context_exitInner (exprNode exp)
02873 {
02874
02875 llassertprint (gc.inclause == NOCLAUSE || gc.inclause == CASECLAUSE,
02876 ("inclause = %s", clause_nameTaken (gc.inclause)));
02877
02878 clauseStack_removeFirst (gc.clauses, NOCLAUSE);
02879 gc.inclause = topClause (gc.clauses);
02880
02881 if (gc.kind == CX_INNER)
02882 {
02883 if (--gc.cont.cdepth == 0)
02884 {
02885 gc.kind = CX_GLOBAL;
02886 gc.cont.glob = TRUE;
02887 }
02888 }
02889 else
02890 {
02891 if (gc.kind == CX_GLOBAL)
02892 {
02893 llcontbuglit ("Attempt to exit global context");
02894 return;
02895 }
02896 }
02897
02898 usymtab_exitScope (exp);
02899 }
02900
02901
02902 void
02903 context_enterStructInnerContext (void)
02904 {
02905 if (gc.kind == CX_GLOBAL)
02906 {
02907 gc.kind = CX_INNER;
02908 gc.cont.cdepth = 1;
02909 }
02910 else if (gc.kind == CX_INNER)
02911 {
02912 gc.cont.cdepth++;
02913 }
02914 else
02915 {
02916 ;
02917 }
02918
02919 usymtab_enterScope ();
02920 }
02921
02922 void
02923 context_exitStructInnerContext (void)
02924 {
02925 if (gc.kind == CX_INNER)
02926 {
02927 if (--gc.cont.cdepth == 0)
02928 {
02929 gc.kind = CX_GLOBAL;
02930 gc.cont.glob = TRUE;
02931 }
02932 }
02933 else
02934 {
02935 if (gc.kind == CX_GLOBAL)
02936 {
02937 llcontbuglit ("Attempt to exit global context");
02938 return;
02939 }
02940 }
02941
02942 usymtab_exitScope (exprNode_undefined);
02943 }
02944
02945 void
02946 context_exitInnerSafe (void)
02947 {
02948
02949 if (gc.kind == CX_INNER)
02950 {
02951 if (--gc.cont.cdepth == 0)
02952 {
02953 gc.cont.cdepth++;
02954 }
02955 }
02956 else if (gc.kind == CX_GLOBAL)
02957 {
02958 llcontbuglit ("Attempt to exit global context");
02959 return;
02960 }
02961 else
02962 {
02963 if (usymtab_inDeepScope ())
02964 {
02965 usymtab_exitScope (exprNode_undefined);
02966 }
02967 }
02968 }
02969
02970 static
02971 void setModuleAccess (void)
02972 {
02973 gc.facct = typeIdSet_emptySet ();
02974
02975 if (fileId_isValid (currentFile ()))
02976 {
02977 cstring baseName = fileloc_getBase (g_currentloc);
02978
02979 if (context_getFlag (FLG_ACCESSFILE))
02980 {
02981 if (usymtab_existsType (baseName))
02982 {
02983 gc.facct = typeIdSet_insert (gc.facct,
02984 usymtab_getTypeId (baseName));
02985 }
02986 else
02987 {
02988 ;
02989 }
02990 }
02991
02992 if (context_getFlag (FLG_ACCESSMODULE))
02993 {
02994 int i;
02995 bool hasaccess = FALSE;
02996
02997 for (i = 0; i < gc.nmods; i++)
02998 {
02999 if (cstring_equal (baseName, gc.moduleaccess[i].file))
03000 {
03001 gc.facct = typeIdSet_union (gc.facct, gc.moduleaccess[i].daccess);
03002
03003 hasaccess = TRUE;
03004 break;
03005 }
03006 }
03007 }
03008
03009 gc.acct = gc.facct;
03010 gc.inheader = fileId_isHeader (currentFile ());
03011 }
03012 else
03013 {
03014 llcontbuglit ("Current file not defined\n");
03015 gc.facct = typeIdSet_emptySet ();
03016 gc.acct = gc.facct;
03017 gc.inheader = FALSE;
03018 }
03019
03020
03021
03022 gc.nacct = typeIdSet_emptySet ();
03023 }
03024
03025 static void
03026 context_enterFileAux (void)
03027 {
03028 setModuleAccess ();
03029 }
03030
03031 void
03032 context_enterFile (void)
03033 {
03034 context_enterFileAux ();
03035 usymtab_enterFile ();
03036 }
03037
03038 void
03039 context_enterMacroFile (void)
03040 {
03041 context_enterFileAux ();
03042 }
03043
03044 bool
03045 context_inFunction (void)
03046 {
03047 kcontext ck = gc.kind;
03048
03049 return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN) || (ck == CX_INNER));
03050 }
03051
03052 bool
03053 context_inFunctionLike (void)
03054 {
03055 return (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN
03056 || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
03057 }
03058
03059 bool
03060 context_inRealFunction (void)
03061 {
03062 kcontext ck = gc.kind;
03063
03064 return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN));
03065 }
03066
03067 void
03068 context_processAllMacros (void)
03069 {
03070 usymtab_enterFile ();
03071
03072 gc.inmacrocache = TRUE;
03073 macrocache_processUndefinedElements (gc.mc);
03074 cleanupMessages ();
03075 usymtab_exitFile ();
03076
03077 gc.inmacrocache = FALSE;
03078 macrocache_finalize ();
03079 }
03080
03081
03082
03083
03084
03085
03086
03087
03088 static void
03089 context_processMacros (void)
03090 {
03091 if (fileId_isValid (currentFile ()))
03092 {
03093 fileloc lastfl;
03094 cstring cbase = cstring_fromChars
03095 (removePathFree
03096 (removeAnyExtension
03097 (cstring_toCharsSafe (fileName (currentFile ())))));
03098
03099 gc.inmacrocache = TRUE;
03100
03101 DPRINTF (("Processing macros: %s", cbase));
03102 lastfl = macrocache_processFileElements (gc.mc, cbase);
03103 DPRINTF (("Processing macros: %s", fileloc_unparse (lastfl)));
03104
03105 cstring_free (cbase);
03106
03107 if (fileloc_isDefined (lastfl))
03108 {
03109 g_currentloc = fileloc_update (g_currentloc, lastfl);
03110 cleanupMessages ();
03111 }
03112
03113 gc.inmacrocache = FALSE;
03114 }
03115 }
03116
03117 bool
03118 context_processingMacros (void)
03119 {
03120 return (gc.inmacrocache);
03121 }
03122
03123 void
03124 context_exitFile (void)
03125 {
03126 if (gc.kind != CX_GLOBAL)
03127 {
03128 llfatalerrorLoc
03129 (cstring_makeLiteral ("File ended outside global scope"));
03130 }
03131
03132 if (gc.insuppressregion)
03133 {
03134
03135 gc.insuppressregion = FALSE;
03136 llerrorlit (FLG_SYNTAX,
03137 "File ended in ignore errors region, "
03138 "possible missing /*@end*/");
03139 }
03140
03141
03142
03143 while (!usymtab_inFileScope ())
03144 {
03145 usymtab_quietExitScope (g_currentloc);
03146 }
03147
03148
03149
03150
03151
03152 sRefSetList_elements (gc.modrecs, mods)
03153 {
03154 sRefSet_clearStatics (mods);
03155 } end_sRefSetList_elements ;
03156
03157 sRefSetList_clear (gc.modrecs);
03158
03159 context_processMacros ();
03160 cleanupMessages ();
03161
03162 usymtab_exitFile ();
03163
03164 gc.inDerivedFile = FALSE;
03165 filelocStack_clear (gc.locstack);
03166
03167 gc.nacct = typeIdSet_emptySet ();
03168
03169 gc.cont.glob = TRUE;
03170
03171 if (gc.savedFlags)
03172 {
03173 context_restoreFlagSettings ();
03174 gc.savedFlags = FALSE;
03175 }
03176 }
03177
03178 void
03179 context_exitMacroCache (void)
03180 {
03181 if (gc.kind != CX_GLOBAL)
03182 {
03183 if (context_inMacro ())
03184 {
03185 context_exitFunction ();
03186 }
03187 else
03188 {
03189 llcontbug (message ("context_exitMacroCache: outside global scope: %q",
03190 context_unparse ()));
03191 gc.kind = CX_GLOBAL;
03192 }
03193 }
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204 gc.cont.glob = TRUE;
03205 }
03206
03207 void
03208 context_saveLocation (void)
03209 {
03210
03211 fileloc_free (gc.saveloc);
03212
03213
03214 gc.saveloc = fileloc_copy (g_currentloc);
03215 }
03216
03217 fileloc
03218 context_getSaveLocation (void)
03219 {
03220 fileloc fl = gc.saveloc;
03221
03222 gc.saveloc = fileloc_undefined;
03223 return fl;
03224 }
03225
03226 cstring
03227 context_inFunctionName (void)
03228 {
03229 if (gc.kind == CX_FUNCTION
03230 || gc.kind == CX_MACROFCN || gc.kind == CX_UNKNOWNMACRO
03231 || gc.kind == CX_MACROCONST
03232 || gc.kind == CX_ITERDEF || gc.kind == CX_ITEREND)
03233 {
03234 return (uentry_rawName (gc.cont.fcn));
03235 }
03236 else
03237 {
03238 llcontbuglit ("context_inFunctionName: not in function");
03239 return (cstring_undefined);
03240 }
03241 }
03242
03243 void
03244 context_userSetFlag (flagcode f, bool b)
03245 {
03246 DPRINTF (("set flag: %s", flagcode_name (f)));
03247
03248 if (f == FLG_NEVERINCLUDE && b)
03249 {
03250 if (gc.flags[FLG_EXPORTHEADER])
03251 {
03252 flagWarning (cstring_makeLiteralTemp
03253 ("setting +neverinclude after +exportheader. "
03254 "Turning off exportheader, since headers are not checked "
03255 "when +neverinclude is used."));
03256
03257 gc.flags[FLG_EXPORTHEADER] = FALSE;
03258 }
03259 }
03260 else
03261 {
03262 if (f == FLG_EXPORTHEADER && b)
03263 {
03264 if (gc.flags[FLG_NEVERINCLUDE])
03265 {
03266 flagWarning (cstring_makeLiteralTemp
03267 ("setting +exportheader after +neverinclude. "
03268 "Not setting exportheader, since headers are not checked "
03269 "when +neverinclude is used."));
03270 gc.flags[FLG_EXPORTHEADER] = FALSE;
03271 return;
03272 }
03273 }
03274 }
03275
03276 if (context_getFlag (FLG_WARNFLAGS) && f != FLG_NOF && f != FLG_OPTF)
03277 {
03278 bool lastsetting = context_getFlag (f);
03279
03280 if (bool_equal (lastsetting, b)
03281 && !flagcode_isSpecialFlag (f)
03282 && !flagcode_isIdemFlag (f)
03283 && !flagcode_hasArgument (f))
03284 {
03285 cstring warn = message ("setting %s%s redundant with current value",
03286 cstring_makeLiteralTemp (b ? "+" : "-"),
03287 flagcode_name (f));
03288 flagWarning (warn);
03289 cstring_free (warn);
03290 }
03291 }
03292
03293 if (flagcode_isLibraryFlag (f))
03294 {
03295 if (gc.library != FLG_ANSILIB
03296 && gc.library != f)
03297 {
03298 cstring warn = message ("selecting library %s after library %s was "
03299 "selected (only one library may be used)",
03300 flagcode_name (f),
03301 flagcode_name (gc.library));
03302 flagWarning (warn);
03303 cstring_free (warn);
03304 }
03305
03306 if (f == FLG_UNIXLIB)
03307 {
03308 if (context_getFlag (FLG_WARNUNIXLIB))
03309 {
03310 flagWarning (cstring_makeLiteralTemp
03311 ("selecting unix library. Unix library is "
03312 "ad hoc addition to POSIX library. Recommend "
03313 "use +posixlib to select POSIX library instead. "
03314 "Use -warnunixlib to suppress this message."));
03315 }
03316 }
03317
03318 gc.library = f;
03319 }
03320
03321 gc.setGlobally[f] = TRUE;
03322 context_setFlag (f, b);
03323 }
03324
03325 void
03326 context_fileSetFlag (flagcode f, ynm set)
03327 {
03328 if (!gc.savedFlags)
03329 {
03330 context_saveFlagSettings ();
03331 }
03332
03333 if (ynm_isOff (set))
03334 {
03335 context_setFlagAux (f, FALSE, TRUE, FALSE);
03336 }
03337 else if (ynm_isOn (set))
03338 {
03339 context_setFlagAux (f, TRUE, TRUE, FALSE);
03340 gc.setLocally[f] = TRUE;
03341 }
03342 else
03343 {
03344 context_restoreFlag (f);
03345 }
03346 }
03347
03348 static void
03349 context_restoreFlag (flagcode f)
03350 {
03351
03352 if (!gc.savedFlags)
03353 {
03354 voptgenerror
03355 (FLG_SYNTAX,
03356 message ("Attempt to restore flag %s when no file scope flags "
03357 "have been set.",
03358 flagcode_unparse (f)),
03359 g_currentloc);
03360 }
03361 else
03362 {
03363 context_addFlagMarker (f, MAYBE);
03364 context_setFlagAux (f, gc.saveflags[f], FALSE, TRUE);
03365 }
03366
03367 }
03368
03369 static void
03370 context_setFlag (flagcode f, bool b)
03371 {
03372 context_setFlagAux (f, b, FALSE, FALSE);
03373 }
03374
03375 void
03376 context_setFlagTemp (flagcode f, bool b)
03377 {
03378 DPRINTF (("Set flag temp: %s / %s", flagcode_unparse (f), bool_unparse (b)));
03379 gc.flags[f] = b;
03380 }
03381
03382
03383 # define DOSET(ff,b) \
03384 do { if (inFile) { gc.setLocally[ff] = TRUE; \
03385 context_addFlagMarker (ff, ynm_fromBool (b)); } \
03386 DPRINTF (("set flag: %s / %s", flagcode_name (ff), bool_unparse (b))); \
03387 gc.flags[ff] = b; } while (FALSE)
03388
03389 static void
03390 context_setFlagAux (flagcode f, bool b, bool
03391 inFile, bool isRestore)
03392 {
03393 DPRINTF (("set flag: %s / %s", flagcode_unparse (f), bool_unparse (b)));
03394
03395 if (f == FLG_USESTDERR)
03396 {
03397 if (b) {
03398 g_msgstream = stderr;
03399 } else {
03400 g_msgstream = stdout;
03401 }
03402 }
03403
03404 if (flagcode_isSpecialFlag (f))
03405 {
03406 gc.flags[f] = b;
03407
03408
03409 switch (f)
03410 {
03411 case FLG_ALLEMPTY:
03412 DOSET (FLG_ALLEMPTY, b);
03413 DOSET (FLG_IFEMPTY, b);
03414 DOSET (FLG_WHILEEMPTY, b);
03415 DOSET (FLG_FOREMPTY, b);
03416 break;
03417 case FLG_PREDBOOL:
03418 DOSET (FLG_PREDBOOL, b);
03419 DOSET (FLG_PREDBOOLINT, b);
03420 DOSET (FLG_PREDBOOLPTR, b);
03421 DOSET (FLG_PREDBOOLOTHERS, b);
03422 break;
03423 case FLG_GLOBALIAS:
03424 DOSET (FLG_CHECKSTRICTGLOBALIAS, b);
03425 DOSET (FLG_CHECKEDGLOBALIAS, b);
03426 DOSET (FLG_CHECKMODGLOBALIAS, b);
03427 DOSET (FLG_UNCHECKEDGLOBALIAS, b);
03428 break;
03429 case FLG_ALLBLOCK:
03430 DOSET (FLG_ALLBLOCK, b);
03431 DOSET (FLG_IFBLOCK, b);
03432 DOSET (FLG_WHILEBLOCK, b);
03433 DOSET (FLG_FORBLOCK, b);
03434 break;
03435 case FLG_GRAMMAR:
03436 if (b)
03437 {
03438 yydebug = 1;
03439 }
03440 else
03441 {
03442 yydebug = 0;
03443 }
03444
03445 DOSET (FLG_GRAMMAR, b);
03446 break;
03447 case FLG_CODEIMPONLY:
03448 DOSET (FLG_CODEIMPONLY, b);
03449 DOSET (FLG_GLOBIMPONLY, b);
03450 DOSET (FLG_RETIMPONLY, b);
03451 DOSET (FLG_STRUCTIMPONLY, b);
03452 break;
03453 case FLG_SPECALLIMPONLY:
03454 DOSET (FLG_SPECALLIMPONLY, b);
03455 DOSET (FLG_SPECGLOBIMPONLY, b);
03456 DOSET (FLG_SPECRETIMPONLY, b);
03457 DOSET (FLG_SPECSTRUCTIMPONLY, b);
03458 break;
03459 case FLG_ALLIMPONLY:
03460 DOSET (FLG_ALLIMPONLY, b);
03461 DOSET (FLG_GLOBIMPONLY, b);
03462 DOSET (FLG_RETIMPONLY, b);
03463 DOSET (FLG_STRUCTIMPONLY, b);
03464 DOSET (FLG_SPECGLOBIMPONLY, b);
03465 DOSET (FLG_SPECRETIMPONLY, b);
03466 DOSET (FLG_SPECSTRUCTIMPONLY, b);
03467 break;
03468 case FLG_ANSILIMITS:
03469 DOSET (FLG_ANSILIMITS, b);
03470 DOSET (FLG_CONTROLNESTDEPTH, b);
03471 DOSET (FLG_STRINGLITERALLEN, b);
03472 DOSET (FLG_INCLUDENEST, b);
03473 DOSET (FLG_NUMSTRUCTFIELDS, b);
03474 DOSET (FLG_NUMENUMMEMBERS, b);
03475
03476 if (b)
03477 {
03478 context_setValue (FLG_CONTROLNESTDEPTH, DEFAULT_CONTROLNESTDEPTH);
03479 context_setValue (FLG_STRINGLITERALLEN, DEFAULT_STRINGLITERALLEN);
03480 context_setValue (FLG_INCLUDENEST, DEFAULT_INCLUDENEST);
03481 context_setValue (FLG_NUMSTRUCTFIELDS, DEFAULT_NUMSTRUCTFIELDS);
03482 context_setValue (FLG_NUMENUMMEMBERS, DEFAULT_NUMENUMMEMBERS);
03483 }
03484 break;
03485 case FLG_EXTERNALNAMELEN:
03486 DOSET (FLG_DISTINCTEXTERNALNAMES, TRUE);
03487 DOSET (FLG_EXTERNALNAMELEN, TRUE);
03488 break;
03489 case FLG_INTERNALNAMELEN:
03490 DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
03491 DOSET (FLG_INTERNALNAMELEN, TRUE);
03492 break;
03493 case FLG_EXTERNALNAMECASEINSENSITIVE:
03494 DOSET (FLG_EXTERNALNAMECASEINSENSITIVE, b);
03495
03496 if (b && !gc.flags[FLG_DISTINCTEXTERNALNAMES])
03497 {
03498 DOSET (FLG_DISTINCTEXTERNALNAMES, TRUE);
03499 context_setValue (FLG_EXTERNALNAMELEN, 0);
03500 }
03501 break;
03502 case FLG_INTERNALNAMECASEINSENSITIVE:
03503 DOSET (FLG_INTERNALNAMECASEINSENSITIVE, b);
03504
03505 if (b && !gc.flags[FLG_DISTINCTINTERNALNAMES])
03506 {
03507 DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
03508 context_setValue (FLG_INTERNALNAMELEN, 0);
03509 }
03510 break;
03511 case FLG_INTERNALNAMELOOKALIKE:
03512 DOSET (FLG_INTERNALNAMELOOKALIKE, b);
03513
03514 if (b && !gc.flags[FLG_DISTINCTINTERNALNAMES])
03515 {
03516 DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
03517 context_setValue (FLG_INTERNALNAMELEN, 0);
03518 }
03519 break;
03520 case FLG_MODUNSPEC:
03521 DOSET (FLG_MODNOMODS, b);
03522 DOSET (FLG_MODGLOBSUNSPEC, b);
03523 DOSET (FLG_MODSTRICTGLOBSUNSPEC, b);
03524 break;
03525 case FLG_EXPORTANY:
03526 DOSET (FLG_EXPORTVAR, b);
03527 DOSET (FLG_EXPORTFCN, b);
03528 DOSET (FLG_EXPORTTYPE, b);
03529 DOSET (FLG_EXPORTMACRO, b);
03530 DOSET (FLG_EXPORTCONST, b);
03531 gc.anyExports = TRUE;
03532 break;
03533 case FLG_REPEXPOSE:
03534 DOSET (FLG_RETEXPOSE, b);
03535 DOSET (FLG_ASSIGNEXPOSE, b);
03536 DOSET (FLG_CASTEXPOSE, b);
03537 break;
03538 case FLG_RETVAL:
03539 DOSET (FLG_RETVALBOOL, b);
03540 DOSET (FLG_RETVALINT, b);
03541 DOSET (FLG_RETVALOTHER, b);
03542 break;
03543 case FLG_PARTIAL:
03544 if (b)
03545 {
03546 DOSET (FLG_EXPORTLOCAL, FALSE);
03547 DOSET (FLG_DECLUNDEF, FALSE);
03548 DOSET (FLG_SPECUNDEF, FALSE);
03549 DOSET (FLG_TOPUNUSED, FALSE);
03550 }
03551 break;
03552 case FLG_DEEPBREAK:
03553 DOSET (FLG_LOOPLOOPBREAK, b);
03554 DOSET (FLG_LOOPSWITCHBREAK, b);
03555 DOSET (FLG_SWITCHLOOPBREAK, b);
03556 DOSET (FLG_SWITCHSWITCHBREAK, b);
03557 DOSET (FLG_LOOPLOOPCONTINUE, b);
03558 DOSET (FLG_DEEPBREAK, b);
03559 break;
03560 case FLG_ACCESSALL:
03561 DOSET (FLG_ACCESSMODULE, b);
03562 DOSET (FLG_ACCESSFILE, b);
03563 DOSET (FLG_ACCESSCZECH, b);
03564 break;
03565 case FLG_ALLMACROS:
03566 DOSET (FLG_ALLMACROS, b);
03567 DOSET (FLG_FCNMACROS, b);
03568 DOSET (FLG_CONSTMACROS, b);
03569 break;
03570 case FLG_CZECH:
03571 if (b) { DOSET (FLG_ACCESSCZECH, b); }
03572 DOSET (FLG_CZECHFUNCTIONS, b);
03573 DOSET (FLG_CZECHVARS, b);
03574 DOSET (FLG_CZECHCONSTANTS, b);
03575 DOSET (FLG_CZECHTYPES, b);
03576 break;
03577 case FLG_SLOVAK:
03578 if (b) { DOSET (FLG_ACCESSSLOVAK, b); }
03579 DOSET (FLG_SLOVAKFUNCTIONS, b);
03580 DOSET (FLG_SLOVAKVARS, b);
03581 DOSET (FLG_SLOVAKCONSTANTS, b);
03582 DOSET (FLG_SLOVAKTYPES, b);
03583 break;
03584 case FLG_CZECHOSLOVAK:
03585 if (b) { DOSET (FLG_ACCESSCZECHOSLOVAK, b); }
03586 DOSET (FLG_CZECHOSLOVAKFUNCTIONS, b);
03587 DOSET (FLG_CZECHOSLOVAKVARS, b);
03588 DOSET (FLG_CZECHOSLOVAKCONSTANTS, b);
03589 DOSET (FLG_CZECHOSLOVAKTYPES, b);
03590 break;
03591 case FLG_NULL:
03592 DOSET (FLG_NULLSTATE, b);
03593 DOSET (FLG_NULLDEREF, b);
03594 DOSET (FLG_NULLASSIGN, b);
03595 DOSET (FLG_NULLPASS, b);
03596 DOSET (FLG_NULLRET, b);
03597 break;
03598 case FLG_MEMCHECKS:
03599 DOSET (FLG_NULLSTATE, b);
03600 DOSET (FLG_NULLDEREF, b);
03601 DOSET (FLG_NULLASSIGN, b);
03602 DOSET (FLG_NULLPASS, b);
03603 DOSET (FLG_NULLRET, b);
03604 DOSET (FLG_COMPDEF, b);
03605 DOSET (FLG_COMPMEMPASS, b);
03606 DOSET (FLG_UNIONDEF, b);
03607 DOSET (FLG_MEMTRANS, b);
03608 DOSET (FLG_USERELEASED, b);
03609 DOSET (FLG_ALIASUNIQUE, b);
03610 DOSET (FLG_MAYALIASUNIQUE, b);
03611 DOSET (FLG_MUSTFREE, b);
03612 DOSET (FLG_MUSTDEFINE, b);
03613 DOSET (FLG_GLOBSTATE, b);
03614 DOSET (FLG_COMPDESTROY, b);
03615 DOSET (FLG_MUSTNOTALIAS, b);
03616 DOSET (FLG_MEMIMPLICIT, b);
03617 DOSET (FLG_BRANCHSTATE, b);
03618
03619 case FLG_MEMTRANS:
03620 DOSET (FLG_MEMTRANS, b);
03621 DOSET (FLG_EXPOSETRANS, b);
03622 DOSET (FLG_OBSERVERTRANS, b);
03623 DOSET (FLG_DEPENDENTTRANS, b);
03624 DOSET (FLG_NEWREFTRANS, b);
03625 DOSET (FLG_ONLYTRANS, b);
03626 DOSET (FLG_OWNEDTRANS, b);
03627 DOSET (FLG_FRESHTRANS, b);
03628 DOSET (FLG_SHAREDTRANS, b);
03629 DOSET (FLG_TEMPTRANS, b);
03630 DOSET (FLG_KEPTTRANS, b);
03631 DOSET (FLG_REFCOUNTTRANS, b);
03632 DOSET (FLG_STATICTRANS, b);
03633 DOSET (FLG_UNKNOWNTRANS, b);
03634 DOSET (FLG_KEEPTRANS, b);
03635 DOSET (FLG_IMMEDIATETRANS, b);
03636 break;
03637
03638 default:
03639 llcontbug (message ("Unhandled special flag: %s",
03640 flagcode_unparse (f)));
03641 break;
03642 }
03643 }
03644 else
03645 {
03646 if (flagcode_isIdemFlag (f))
03647 {
03648 DOSET (f, TRUE);
03649 }
03650 else
03651 {
03652 if (b && !gc.anyExports
03653 && (f == FLG_EXPORTVAR || f == FLG_EXPORTFCN
03654 || f == FLG_EXPORTTYPE || f == FLG_EXPORTMACRO
03655 || f == FLG_EXPORTCONST
03656 || f == FLG_EXPORTANY))
03657 {
03658 gc.anyExports = TRUE;
03659 }
03660
03661 DOSET (f, b);
03662 }
03663 }
03664 }
03665
03666 bool
03667 context_maybeSet (flagcode d)
03668 {
03669 return (gc.flags[d] || gc.setLocally[d]);
03670 }
03671
03672 bool
03673 context_getFlag (flagcode d)
03674 {
03675 return (gc.flags[d]);
03676 }
03677
03678 static void context_saveFlagSettings (void)
03679 {
03680 gc.savedFlags = TRUE;
03681 llassert (sizeof (gc.saveflags) == sizeof (gc.flags));
03682 memcpy (gc.saveflags, gc.flags, sizeof (gc.flags));
03683 }
03684
03685 static void context_restoreFlagSettings (void)
03686 {
03687 llassert (sizeof (gc.saveflags) == sizeof (gc.flags));
03688 memcpy (gc.flags, gc.saveflags, sizeof (gc.flags));
03689 gc.savedFlags = FALSE;
03690 }
03691
03692 void context_setFilename (fileId fid, int lineno)
03693
03694
03695 {
03696 if (fileId_baseEqual (currentFile (), fid))
03697 {
03698 setLine (lineno);
03699 return;
03700 }
03701 else
03702 {
03703 fileloc_setColumn (g_currentloc, 0);
03704
03705 if (fileloc_isSpecialFile (g_currentloc))
03706 {
03707 gc.inDerivedFile = TRUE;
03708 }
03709
03710 if (filelocStack_popPushFile (gc.locstack, g_currentloc))
03711 {
03712 int maxdepth = context_getValue (FLG_INCLUDENEST);
03713
03714 if (filelocStack_size (gc.locstack) > maxdepth)
03715 {
03716 int depth = filelocStack_includeDepth (gc.locstack);
03717
03718 if (depth > maxdepth)
03719 {
03720 if (optgenerror
03721 (FLG_INCLUDENEST,
03722 message ("Maximum include nesting depth "
03723 "(%d, current depth %d) exceeded",
03724 maxdepth,
03725 depth),
03726 filelocStack_nextTop (gc.locstack)))
03727 {
03728 filelocStack_printIncludes (gc.locstack);
03729 }
03730 }
03731 }
03732 }
03733
03734 g_currentloc = fileloc_create (fid, lineno, 1);
03735 gc.inheader = fileId_isHeader (currentFile ());
03736
03737 context_enterFileAux ();
03738 }
03739 }
03740
03741 void context_enterIterDef ( uentry le)
03742 {
03743 context_enterMacro (le);
03744 gc.acct = typeIdSet_subtract (gc.facct, gc.nacct);
03745 gc.kind = CX_ITERDEF;
03746 }
03747
03748 void context_enterIterEnd ( uentry le)
03749 {
03750 context_enterMacro (le);
03751 gc.kind = CX_ITEREND;
03752 }
03753
03754 void
03755 context_destroyMod (void)
03756
03757 {
03758 setCodePoint ();
03759 ctype_destroyMod ();
03760 setCodePoint ();
03761 usymtab_free ();
03762 setCodePoint ();
03763 fileTable_free (gc.ftab);
03764 filelocStack_free (gc.locstack);
03765 setCodePoint ();
03766 gc.ftab = fileTable_undefined;
03767
03768 macrocache_free (gc.mc);
03769 sfree (gc.moduleaccess);
03770 setCodePoint ();
03771
03772 fileloc_free (gc.saveloc); gc.saveloc = fileloc_undefined;
03773 fileloc_free (gc.pushloc); gc.pushloc = fileloc_undefined;
03774
03775 setCodePoint ();
03776 sRefSetList_free (gc.modrecs);
03777 setCodePoint ();
03778 flagMarkerList_free (gc.markers);
03779 setCodePoint ();
03780 messageLog_free (gc.msgLog);
03781 setCodePoint ();
03782 clauseStack_free (gc.clauses);
03783 setCodePoint ();
03784
03785 cstring_free (gc.msgAnnote);
03786 globSet_free (gc.globs_used);
03787 }
03788
03789
03790
03791
03792
03793 bool context_msgBoolInt (void)
03794 {
03795 return gc.flags [FLG_BOOLINT];
03796 }
03797
03798 bool context_msgCharInt (void)
03799 {
03800 return gc.flags [FLG_CHARINT];
03801 }
03802
03803 bool context_msgEnumInt (void)
03804 {
03805 return gc.flags [FLG_ENUMINT];
03806 }
03807
03808 bool context_msgPointerArith (void)
03809 {
03810 return gc.flags [FLG_POINTERARITH];
03811 }
03812
03813 bool context_msgStrictOps (void)
03814 {
03815 return gc.flags [FLG_STRICTOPS];
03816 }
03817
03818 # ifndef NOLCL
03819 bool context_msgLh (void)
03820 {
03821 return gc.flags [FLG_DOLH];
03822 }
03823 # endif
03824
03825 void context_pushLoc (void)
03826 {
03827 fileloc_free (gc.pushloc);
03828 gc.pushloc = gc.saveloc;
03829 gc.saveloc = fileloc_undefined;
03830 }
03831
03832 void context_popLoc (void)
03833 {
03834 gc.saveloc = fileloc_update (gc.saveloc, gc.pushloc);
03835 }
03836
03837 bool context_inGlobalScope (void)
03838 {
03839 return (usymtab_inFileScope() || usymtab_inGlobalScope ());
03840 }
03841
03842 bool context_inInnerScope (void)
03843 {
03844 return (gc.kind == CX_INNER);
03845 }
03846
03847 void context_setProtectVars (void)
03848 {
03849 gc.protectVars = TRUE;
03850 }
03851
03852 bool context_anyErrors (void)
03853 {
03854 return (gc.numerrors > 0);
03855 }
03856
03857 void context_hasError (void)
03858 {
03859 gc.numerrors++;
03860 }
03861
03862 int context_numErrors (void)
03863 {
03864 return gc.numerrors;
03865 }
03866
03867 bool context_neednl (void)
03868 {
03869 return gc.neednl;
03870 }
03871
03872 void context_setNeednl (void)
03873 {
03874 gc.neednl = TRUE;
03875 }
03876
03877 int context_getExpect (void)
03878 {
03879 return (context_getValue (FLG_EXPECT));
03880 }
03881
03882 # ifndef NOLCL
03883 int context_getLCLExpect (void)
03884 {
03885 return (context_getValue (FLG_LCLEXPECT));
03886 }
03887 # endif
03888
03889 int context_getLimit (void)
03890 {
03891 return (context_getValue (FLG_LIMIT));
03892 }
03893
03894 bool context_unlimitedMessages (void)
03895 {
03896 return (context_getLimit () < 0);
03897 }
03898
03899 void context_releaseVars (void)
03900 {
03901 llassert (gc.protectVars);
03902 gc.protectVars = FALSE;
03903 }
03904
03905 void context_sizeofReleaseVars (void)
03906 {
03907
03908
03909
03910
03911 gc.protectVars = FALSE;
03912 }
03913
03914 bool context_inProtectVars (void)
03915 {
03916 return (gc.protectVars);
03917 }
03918
03919 void context_hideShowscan (void)
03920 {
03921 gc.flags[FLG_SHOWSCAN] = FALSE;
03922 }
03923
03924 void context_unhideShowscan (void)
03925 {
03926 gc.flags[FLG_SHOWSCAN] = TRUE;
03927 }
03928
03929 bool context_inHeader (void)
03930 {
03931 return (gc.inheader);
03932 }
03933
03934 fileTable context_fileTable (void)
03935 {
03936 return gc.ftab;
03937 }
03938
03939 cstring context_tmpdir (void)
03940 {
03941 return (context_getString (FLG_TMPDIR));
03942 }
03943
03944 messageLog context_messageLog (void)
03945 {
03946 return gc.msgLog;
03947 }
03948
03949 bool context_inMacroFunction (void)
03950 {
03951 return (gc.kind == CX_MACROFCN);
03952 }
03953
03954 bool context_inMacroConstant (void)
03955 {
03956 return (gc.kind == CX_MACROCONST);
03957 }
03958
03959 bool context_inMacroUnknown (void)
03960 {
03961 return (gc.kind == CX_UNKNOWNMACRO);
03962 }
03963
03964 void context_setShownFunction (void)
03965 {
03966 gc.showfunction = FALSE;
03967 }
03968
03969 bool context_doDump (void)
03970 {
03971 return cstring_isNonEmpty (context_getString (FLG_DUMP));
03972 }
03973
03974 bool context_doMerge (void)
03975 {
03976 return cstring_isNonEmpty (context_getString (FLG_MERGE));
03977 }
03978
03979 cstring context_getDump (void)
03980 {
03981 return context_getString (FLG_DUMP);
03982 }
03983
03984 cstring context_getMerge (void)
03985 {
03986 return context_getString (FLG_MERGE);
03987 }
03988
03989 # ifndef NOLCL
03990 bool context_inLCLLib (void)
03991 {
03992 return (gc.kind == CX_LCLLIB);
03993 }
03994
03995 bool context_inImport (void)
03996 {
03997 return (gc.inimport);
03998 }
03999
04000 void context_enterImport (void)
04001 {
04002 gc.inimport = TRUE;
04003 }
04004
04005 void context_leaveImport (void)
04006 {
04007 gc.inimport = FALSE;
04008 }
04009 # endif
04010
04011 bool context_inMacro (void)
04012 {
04013 return (gc.kind == CX_MACROFCN || gc.kind == CX_MACROCONST
04014 || gc.kind == CX_UNKNOWNMACRO
04015 || gc.kind == CX_ITERDEF || gc.kind == CX_ITEREND);
04016 }
04017
04018 bool context_inIterDef (void)
04019 {
04020 return (gc.kind == CX_ITERDEF);
04021 }
04022
04023 bool context_inIterEnd (void)
04024 {
04025 return (gc.kind == CX_ITEREND);
04026 }
04027
04028 int context_getLinesProcessed (void)
04029 {
04030 return (gc.linesprocessed);
04031 }
04032
04033 int context_getSpecLinesProcessed (void)
04034 {
04035 return (gc.speclinesprocessed);
04036 }
04037
04038 # ifndef NOLCL
04039 void context_processedSpecLine (void)
04040 {
04041 gc.speclinesprocessed++;
04042 }
04043
04044 void context_resetSpecLines (void)
04045 {
04046 gc.speclinesprocessed = 0;
04047 }
04048 # endif
04049
04050 bool context_inGlobalContext (void)
04051 {
04052 return (gc.kind == CX_GLOBAL);
04053 }
04054
04055 void context_setFileId (fileId s)
04056 {
04057 g_currentloc = fileloc_updateFileId (g_currentloc, s);
04058 }
04059
04060 bool context_setBoolName (void)
04061 {
04062 return (!cstring_equalLit (context_getString (FLG_BOOLTYPE),
04063 DEFAULT_BOOLTYPE));
04064 }
04065
04066 cstring context_printBoolName (void)
04067 {
04068 if (context_setBoolName ())
04069 {
04070 return context_getBoolName ();
04071 }
04072 else
04073 {
04074 return cstring_makeLiteralTemp ("boolean");
04075 }
04076 }
04077
04078 cstring context_getBoolName (void)
04079 {
04080 return (context_getString (FLG_BOOLTYPE));
04081 }
04082
04083 cstring context_getFalseName (void)
04084 {
04085 return (context_getString (FLG_BOOLFALSE));
04086 }
04087
04088 cstring context_getTrueName (void)
04089 {
04090 return (context_getString (FLG_BOOLTRUE));
04091 }
04092
04093 cstring context_getLarchPath (void)
04094 {
04095 return (context_getString (FLG_LARCHPATH));
04096 }
04097
04098 cstring context_getLCLImportDir (void)
04099 {
04100 return (context_getString (FLG_LCLIMPORTDIR));
04101 }
04102
04103 static void context_setJustPopped (void)
04104 {
04105 gc.justpopped = TRUE;
04106 }
04107
04108 void context_clearJustPopped (void)
04109 {
04110 gc.justpopped = FALSE;
04111 }
04112
04113 bool context_justPopped (void)
04114 {
04115 return (gc.justpopped);
04116 }
04117
04118 void context_setMacroMissingParams (void)
04119 {
04120 gc.macroMissingParams = TRUE;
04121 }
04122
04123 void context_resetMacroMissingParams (void)
04124 {
04125 gc.macroMissingParams = FALSE;
04126 }
04127
04128 bool context_isMacroMissingParams (void)
04129 {
04130 return (gc.macroMissingParams);
04131 }
04132
04133 void context_showFilelocStack (void)
04134 {
04135 filelocStack_printIncludes (gc.locstack);
04136 }
04137
04138
04139
04140
04141
04142
04143