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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 # include "lclintMacros.nf"
00050 # include "basic.h"
00051 # include "structNames.h"
00052 # include "exprChecks.h"
00053 # include "aliasChecks.h"
00054
00055
00056
00057
00058
00059 static uentryList functypes = uentryList_undefined;
00060
00061 static bool dbgfree = FALSE;
00062 static bool dbgload = TRUE;
00063
00064
00065
00066
00067
00068
00069
00070
00071 static bool noshadowerror = FALSE;
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 static usymtab utab;
00089
00090
00091 static usymtab globtab;
00092 static usymtab filetab;
00093
00094
00095 static usymtab oldtab;
00096
00097 static int usymtab_lexicalLevel (void) ;
00098 static bool usymtab_isProbableNullAltBranch (sRef p_s) ;
00099 static void refTable_free ( refTable p_x, int p_nentries);
00100 static ctype usymtab_suFieldsType (uentryList p_f, bool p_isStruct) ;
00101
00102 static void
00103 usymtab_freeLevel ( usymtab p_u)
00104 ;
00105
00106 static bool usymtab_isProbableNullAux (sRef p_s) ;
00107 static cstring usymtab_unparseStackTab (usymtab p_t);
00108 static uentry
00109 usymtab_getRefTab ( usymtab p_u, int p_level, usymId p_index);
00110 static cstring
00111 usymtab_unparseLocalAux ( usymtab p_s);
00112 static cstring
00113 usymtab_unparseLocalList ( usymtab p_s);
00114 static cstring usymtab_typeName ( usymtab p_t);
00115 static void usymtab_handleParams (void)
00116
00117 ;
00118
00119 static uentry
00120 usymtab_addRefEntry ( usymtab p_s, cstring p_k);
00121 static usymtab
00122 usymtab_dropEnv ( usymtab p_s);
00123 static uentry
00124 usymtab_getRefNoisy ( usymtab p_s, int p_level, usymId p_index);
00125
00126 static uentry
00127 usymtab_lookupQuiet (usymtab p_s, cstring p_k);
00128 static void usymtab_printAllAux (usymtab p_s) ;
00129 static int usymtab_getIndex ( usymtab p_s, cstring p_k);
00130 static uentry usymtab_fetchIndex ( usymtab p_s, int p_i);
00131 static uentry
00132 usymtab_lookupAux (usymtab p_s, cstring p_k);
00133 static usymtab
00134 usymtab_getFileTab (void) ;
00135 static int refTable_lookup ( usymtab p_ut, int p_level, int p_index);
00136 static bool usymtab_mustBreak (usymtab p_s);
00137 static bool usymtab_mustEscape (usymtab p_s);
00138
00139 static void recordFunctionType (uentry ue)
00140 {
00141 llassert (uentry_isDatatype (ue) || uentry_isAnyTag (ue)
00142 || uentry_isEnumConstant (ue));
00143
00144
00145 functypes = uentryList_add (functypes, ue);
00146
00147 }
00148
00149 static void clearFunctionTypes (void)
00150
00151 {
00152 uentryList_elements (functypes, el)
00153 {
00154 if (cstring_isDefined (uentry_rawName (el)))
00155 {
00156 if (globtab->htable != NULL)
00157 {
00158 hashTable_remove (globtab->htable, uentry_rawName (el));
00159 }
00160
00161 uentry_setName (el, cstring_undefined);
00162 }
00163
00164
00165 llassert (uentry_isValid (el));
00166 el->sref = sRef_undefined;
00167
00168 } end_uentryList_elements ;
00169
00170 uentryList_clear (functypes);
00171 }
00172
00173 static bool usymtab_isBranch (usymtab u)
00174 {
00175 return (usymtab_isDefined (u) &&
00176 (u->kind == US_TBRANCH || u->kind == US_FBRANCH
00177 || u->kind == US_CBRANCH || u->kind == US_SWITCH));
00178 }
00179
00180 static bool usymtab_mustBreak (usymtab s)
00181 {
00182 llassert (s != GLOBAL_ENV);
00183 return (s->mustBreak);
00184 }
00185
00186 static bool usymtab_mustEscape (usymtab s)
00187 {
00188 llassert (s != GLOBAL_ENV);
00189 return (exitkind_mustEscape (s->exitCode));
00190 }
00191
00192 void usymtab_setMustBreak ()
00193
00194 {
00195 llassert (utab != GLOBAL_ENV);
00196 utab->mustBreak = TRUE;
00197 }
00198
00199 void usymtab_setExitCode (exitkind ex)
00200
00201 {
00202 llassert (utab != GLOBAL_ENV);
00203
00204 utab->exitCode = ex;
00205
00206 if (exitkind_mustEscape (ex))
00207 {
00208 utab->mustBreak = TRUE;
00209 }
00210 }
00211
00212 bool usymtab_isAltProbablyDeepNull (sRef s)
00213 {
00214 return (sRef_deepPred (usymtab_isProbableNullAltBranch, s));
00215 }
00216
00217 static bool usymtab_isProbableNullAltBranch (sRef s)
00218
00219 {
00220 guardSet t;
00221 bool res;
00222
00223 t = utab->guards;
00224
00225 llassert (utab->env != NULL);
00226
00227
00228 utab->guards = utab->env->guards;
00229 utab->env->guards = t;
00230
00231
00232 llassert (usymtab_isDefined (utab));
00233 res = usymtab_isProbableNull (s);
00234
00235
00236
00237
00238
00239
00240
00241 utab->env->guards = utab->guards;
00242 utab->guards = t;
00243
00244
00245 return res;
00246 }
00247
00248 static usymtab
00249 usymtab_create (uskind kind, usymtab env, bool nextlevel)
00250
00251
00252 {
00253 usymtab t = (usymtab) dmalloc (sizeof (*t));
00254
00255 t->nentries = 0;
00256 t->nspace = CBASESIZE;
00257 t->entries = (uentry *) dmalloc (sizeof (*t->entries) * CBASESIZE);
00258 t->reftable = (nextlevel
00259 ? NULL
00260 : (refentry *) dmalloc (sizeof (*t->reftable) * CBASESIZE));
00261
00262 t->kind = kind;
00263 t->lexlevel = (env == GLOBAL_ENV ? 0 : env->lexlevel) + (nextlevel ? 1 : 0);
00264
00265 t->env = env;
00266 t->htable = NULL;
00267
00268 t->guards = guardSet_undefined;
00269 t->aliases = aliasTable_undefined;
00270
00271 t->mustBreak = FALSE;
00272 t->exitCode = XK_NEVERESCAPE;
00273
00274 return t;
00275 }
00276
00277
00278
00279
00280
00281 static usymtab
00282 usymtab_createRoot (void)
00283 {
00284 usymtab u = (usymtab) dmalloc (sizeof (*u));
00285
00286 u->nentries = 0;
00287 u->nspace = CGLOBBASESIZE;
00288 u->entries = (uentry *) dmalloc (sizeof (*u->entries) * CGLOBBASESIZE);
00289 u->env = GLOBAL_ENV;
00290 u->lexlevel = 0;
00291 u->htable = hashTable_create (CGLOBHASHSIZE);
00292 u->reftable = NULL;
00293
00294 u->guards = guardSet_new ();
00295 u->aliases = aliasTable_new ();
00296
00297 u->mustBreak = FALSE;
00298 u->exitCode = XK_NEVERESCAPE;
00299 u->kind = US_NORMAL;
00300
00301 return (u);
00302 }
00303
00304 void
00305 usymtab_initMod (void)
00306
00307
00308 {
00309 utab = usymtab_createRoot ();
00310 globtab = utab;
00311 filetab = usymtab_undefined;
00312 oldtab = usymtab_undefined;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322 void
00323 usymtab_initBool ()
00324 {
00325 if (context_getFlag (FLG_NOLIB))
00326 {
00327 ctype boolt = ctype_bool;
00328
00329
00330 uentry boolentry = uentry_makeBoolDatatype (YES);
00331 usymtab_supGlobalEntry (boolentry);
00332 context_addBoolAccess ();
00333
00334
00335
00336
00337
00338
00339 usymtab_supGlobalEntry
00340 (uentry_makeConstantAux (context_getFalseName (), boolt,
00341 fileloc_getBuiltin (), FALSE,
00342 multiVal_makeInt (0)));
00343 usymtab_supGlobalEntry
00344 (uentry_makeConstantAux (context_getTrueName (), boolt,
00345 fileloc_getBuiltin (), FALSE,
00346 multiVal_makeInt (1)));
00347 }
00348 }
00349
00350
00351
00352
00353
00354 static void
00355 usymtab_grow ( usymtab s)
00356 {
00357 int i;
00358 o_uentry *oldsyms = s->entries;
00359
00360 s->nspace = CBASESIZE;
00361 s->entries = (uentry *) dmalloc (sizeof (*s->entries)
00362 * (s->nentries + s->nspace));
00363
00364 for (i = 0; i < s->nentries; i++)
00365 {
00366 s->entries[i] = oldsyms[i];
00367 }
00368
00369 sfree (oldsyms);
00370
00371 if (s->reftable != NULL)
00372 {
00373 refTable oldRefs = s->reftable;
00374
00375 s->reftable = (refentry *) dmalloc (sizeof (*s->reftable)
00376 * (s->nentries + CBASESIZE + 1));
00377
00378 for (i = 0; i < s->nentries; i++)
00379 {
00380 s->reftable[i] = oldRefs[i];
00381 }
00382
00383
00384 sfree (oldRefs);
00385
00386 }
00387
00388 }
00389
00390 static void
00391 usymtab_addEntryQuiet ( usymtab s, uentry e)
00392 {
00393 if (!(s->lexlevel > fileScope || !sRef_modInFunction ()))
00394 {
00395 if (uentry_isDatatype (e)
00396 || uentry_isFunction (e)
00397 || uentry_isAnyTag (e)
00398 || uentry_isEnumConstant (e)
00399 || context_inMacro ())
00400 {
00401
00402
00403
00404
00405
00406
00407
00408 e->sref = sRef_saveCopy (e->sref);
00409 }
00410 else
00411 {
00412 llparseerror
00413 (cstring_makeLiteral ("Declaration outside function scope"));
00414
00415 llcontbug (message ("usymtab_addEntryQuiet: inconsistent state "
00416 "(lexlevel = %d, modFunction = %s) adding: %q",
00417 s->lexlevel, bool_unparse (sRef_modInFunction ()),
00418 uentry_unparse (e)));
00419 sRef_setGlobalScope ();
00420
00421 e->sref = sRef_saveCopy (e->sref);
00422 }
00423 }
00424
00425 if (s->nspace <= 0)
00426 {
00427 usymtab_grow (s);
00428 }
00429
00430 s->nspace--;
00431 s->entries[s->nentries] = e;
00432
00433 # ifdef DOANNOTS
00434 if (s == globtab || s == filetab)
00435 {
00436 if (!fileloc_isLib (g_currentloc))
00437 {
00438 uentry_tallyAnnots (e, AN_UNKNOWN);
00439 }
00440 }
00441 # endif
00442
00443 if (s->htable != NULL)
00444 {
00445 hashTable_insert (s->htable, uentry_rawName (e), s->nentries);
00446 }
00447
00448 s->nentries++;
00449 }
00450
00451 static uentry
00452 usymtab_addEntryBase ( usymtab s, uentry e)
00453 {
00454
00455
00456
00457
00458
00459
00460
00461 uentry old;
00462
00463 if (uentry_isValid (old = usymtab_lookupQuiet (s, uentry_rawName (e))))
00464 {
00465 DPRINTF (("Duplicate entry: %s", uentry_unparse (e)));
00466 uentry_free (e);
00467 return old;
00468 }
00469 else
00470 {
00471 int thisentry = s->nentries;
00472
00473 if (uentry_isVar (e))
00474 {
00475 uentry_setSref (e, sRef_makeCvar (globScope, thisentry,
00476 uentry_getType (e)));
00477 }
00478
00479 usymtab_addEntryQuiet (s, e);
00480 return e;
00481 }
00482 }
00483
00484 static usymId
00485 usymtab_addEntryAux ( usymtab st, uentry e, bool isSref)
00486
00487
00488 {
00489 usymId thisentry = st->nentries;
00490
00491 llassert (!uentry_isElipsisMarker (e));
00492
00493
00494
00495
00496
00497
00498 llassertprint (uentry_isAnyTag (e) ? st == globtab : TRUE,
00499 ("non-global tag: %s / %d", uentry_unparseFull (e), st->lexlevel));
00500
00501 if (st->lexlevel == fileScope
00502 && (!(uentry_isStatic (e)) || uentry_isAnyTag (e)))
00503 {
00504 st = globtab;
00505 }
00506
00507 if (isSref)
00508 {
00509 ctype ct = uentry_getType (e);
00510
00511 if (uentry_isFunction (e) && ctype_isFunction (ct))
00512 {
00513 ct = ctype_returnValue (ct);
00514 }
00515
00516 if (uentry_isStatic (e))
00517 {
00518 sRef sr = sRef_makeCvar (st->lexlevel, thisentry, ct);
00519
00520 if (sRef_isStack (sr) || sRef_isLocalState (sr))
00521 {
00522 sRef_setAliasKind (sr, AK_STATIC, uentry_whereLast (e));
00523 sRef_setDefined (sr, uentry_whereLast (e));
00524 }
00525
00526 uentry_setSref (e, sr);
00527 }
00528 else
00529 {
00530 uentry_setSref (e, sRef_makeCvar (st->lexlevel, thisentry, ct));
00531 }
00532
00533 }
00534
00535 if (uentry_isDatatype (e))
00536 {
00537
00538 uentry_setDatatype (e, thisentry);
00539 }
00540
00541 if (uentry_isFunction (e))
00542 {
00543 ctype ct = uentry_getType (e);
00544
00545 if (ctype_isFunction (ct)
00546 && uentryList_isMissingParams (ctype_argsFunction (ct)))
00547 {
00548 if (uentry_isDeclared (e))
00549 {
00550 voptgenerror
00551 (FLG_NOPARAMS,
00552 message ("Function %q declared without parameter list",
00553 uentry_getName (e)),
00554 uentry_whereDeclared (e));
00555 }
00556 else
00557 {
00558 voptgenerror
00559 (FLG_NOPARAMS,
00560 message ("Function %q specified without parameter list",
00561 uentry_getName (e)),
00562 uentry_whereSpecified (e));
00563 }
00564 }
00565 }
00566
00567 if (st == globtab && !uentry_isSpecified (e))
00568 {
00569 exprChecks_checkExport (e);
00570 }
00571
00572
00573 uentry_checkName (e);
00574
00575 usymtab_addEntryQuiet (st, e);
00576 return (thisentry);
00577 }
00578
00579 usymId
00580 usymtab_addEntry (uentry e)
00581
00582
00583 {
00584
00585 llassertprint (!usymtab_exists (uentry_rawName (e)),
00586 ("Entry already exists: %s", uentry_unparse (e)));
00587
00588 return usymtab_addEntryAux (utab, e, FALSE);
00589 }
00590
00591 void
00592 usymtab_addGlobalEntry (uentry e)
00593
00594 {
00595 DPRINTF (("Add global: %s / %s", uentry_unparse (e), bool_unparse (uentry_isForward (e))));
00596
00597 (void) usymtab_addEntryAux (globtab, e, FALSE);
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 static usymId
00609 usymtab_supEntryAux ( usymtab st,
00610 uentry e, bool isSref)
00611
00612
00613 {
00614 cstring ename = uentry_rawName (e);
00615 bool staticEntry = FALSE;
00616 int eindex;
00617
00618
00619 if (st->lexlevel == fileScope
00620 && (!(uentry_isStatic (e)) || uentry_isAnyTag (e)))
00621 {
00622 eindex = usymtab_getIndex (st, ename);
00623
00624 if (eindex != NOT_FOUND)
00625 {
00626 uentry ce = st->entries[eindex];
00627
00628 if (optgenerror
00629 (FLG_SHADOW,
00630 message ("%s %q shadows static declaration",
00631 ekind_capName (uentry_getKind (e)),
00632 uentry_getName (e)),
00633 uentry_whereDeclared (e)))
00634 {
00635 uentry_showWhereLast (ce);
00636 }
00637
00638 if (eindex == st->nentries - 1)
00639 {
00640 ;
00641 }
00642 else
00643 {
00644 st->entries[eindex] = st->entries[st->nentries - 1];
00645 }
00646
00647 if (st->htable != NULL)
00648 {
00649 hashTable_replaceKey (st->htable, uentry_rawName (ce),
00650 uentry_rawName (e));
00651 }
00652
00653 uentry_free (ce);
00654 st->nentries--;
00655 }
00656
00657 st = globtab;
00658 }
00659
00660 if (uentry_isStatic (e)) {
00661 if (uentry_isFunction (e)) {
00662
00663 st = usymtab_getFileTab ();
00664 staticEntry = TRUE;
00665 } else {
00666 if (!uentry_isAnyTag (e) && st == globtab)
00667 {
00668 st = usymtab_getFileTab ();
00669 staticEntry = TRUE;
00670 DPRINTF (("Static entry!"));
00671 }
00672 }
00673 }
00674
00675 DPRINTF (("Using symtab: %s", usymtab_unparseLocalAux (st)));
00676
00677 eindex = usymtab_getIndex (st, ename);
00678
00679 if (eindex != NOT_FOUND)
00680 {
00681 uentry ce = st->entries[eindex];
00682
00683 DPRINTF (("Found entry: %s", uentry_unparse (ce)));
00684
00685 if (uentry_isPriv (ce)
00686
00687 || (uentry_isStatic (ce)
00688 && uentry_isAnyTag (ce)
00689 && (uentry_isDeclared (ce)
00690 && !fileloc_sameFile (uentry_whereDefined (ce),
00691 uentry_whereDefined (e)))))
00692 {
00693
00694
00695
00696
00697
00698 llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
00699
00700 st->entries[eindex] = e;
00701
00702 if (uentry_isDatatype (e))
00703 {
00704 uentry_setDatatype (e, eindex);
00705 }
00706
00707 if (st == globtab && !uentry_isSpecified (e))
00708 {
00709 exprChecks_checkExport (e);
00710 }
00711
00712 if (st->htable != NULL)
00713 {
00714 hashTable_replaceKey (st->htable, uentry_rawName (ce),
00715 uentry_rawName (e));
00716 }
00717
00718 uentry_free (ce);
00719 ce = e;
00720 }
00721 else if (uentry_isSpecified (ce))
00722 {
00723 if (uentry_isSpecified (e))
00724 {
00725 if (fileloc_isImport (uentry_whereSpecified (ce)))
00726 {
00727
00728 if (st->htable != NULL)
00729 {
00730 hashTable_replaceKey (st->htable,
00731 uentry_rawName (ce),
00732 uentry_rawName (e));
00733 }
00734
00735 uentry_free (ce);
00736 st->entries[eindex] = e;
00737 ce = e;
00738
00739 if (uentry_isDatatype (e)) uentry_setDatatype (e, eindex);
00740 }
00741 else
00742 {
00743 if (fileloc_isImport (uentry_whereSpecified (e)))
00744 {
00745 uentry_free (e);
00746 }
00747 else
00748 {
00749
00750
00751 if (uentry_isDatatype (e))
00752 {
00753 uentry_setDatatype (e, eindex);
00754 }
00755
00756 if (st->htable != NULL)
00757 {
00758 hashTable_replaceKey (st->htable,
00759 uentry_rawName (ce),
00760 uentry_rawName (e));
00761 }
00762
00763 llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
00764 uentry_free (ce);
00765 st->entries[eindex] = e;
00766 ce = e;
00767 }
00768 }
00769 }
00770 else
00771 {
00772 if (uentry_isDeclared (ce))
00773 {
00774 llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
00775 uentry_mergeDefinition (ce, e);
00776 }
00777 else
00778 {
00779 llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
00780 uentry_mergeEntries (ce, e);
00781 }
00782 }
00783 }
00784 else
00785 {
00786 if (!(st->lexlevel > fileScope || !sRef_modInFunction ()))
00787 {
00788 if (uentry_isDatatype (e) || uentry_isAnyTag (e)
00789 || uentry_isEnumConstant (e))
00790 {
00791 ;
00792
00793
00794
00795
00796 }
00797 else
00798 {
00799 llcontbug (message ("usymtab_supEntryAux: inconsistent state "
00800 "(lexlevel = %d, modFunction = %s) adding: %q",
00801 st->lexlevel, bool_unparse (sRef_modInFunction ()),
00802 uentry_unparse (e)));
00803
00804 if (sRef_modInFunction ())
00805 {
00806
00807 e->sref = sRef_saveCopy (e->sref);
00808 }
00809 }
00810 }
00811
00812 uentry_mergeDefinition (ce, e);
00813 }
00814
00815 if (isSref)
00816 {
00817 ctype ct = uentry_getType (ce);
00818
00819 if (uentry_isFunction (ce) && ctype_isFunction (ct))
00820 {
00821 ct = ctype_returnValue (ct);
00822 }
00823
00824 uentry_setSref (ce, sRef_makeCvar (st->lexlevel, eindex, ct));
00825 }
00826 }
00827 else
00828 {
00829 uentry outer;
00830
00831 if (st->lexlevel == globScope
00832 && !uentry_isStatic (e)
00833 && !uentry_isExtern (e)
00834 && usymtab_isDefined (filetab))
00835 {
00836
00837
00838
00839
00840
00841
00842
00843
00844 eindex = usymtab_getIndex (filetab, ename);
00845
00846 if (eindex != NOT_FOUND)
00847 {
00848 uentry ce = filetab->entries[eindex];
00849
00850 uentry_setStatic (e);
00851 uentry_mergeDefinition (ce, e);
00852 staticEntry = TRUE;
00853 goto exitPoint;
00854 }
00855 }
00856
00857 outer = usymtab_lookupQuiet (st->env, ename);
00858
00859
00860
00861
00862
00863 if (!noshadowerror
00864 && uentry_isValid (outer)
00865 && !(uentry_isYield (e) || uentry_isYield (outer))
00866 && fileloc_isDefined (uentry_whereLast (e))
00867 && fileloc_isDefined (uentry_whereLast (outer)))
00868 {
00869 if (!uentry_sameKind (outer, e))
00870 {
00871 ;
00872 }
00873 else
00874 {
00875 if (ctype_isUnknown (uentry_getType (outer))
00876 || uentry_isForward (outer))
00877 {
00878 ;
00879 }
00880 else
00881 {
00882 if (optgenerror
00883 (FLG_SHADOW,
00884 message ("%s %q shadows outer declaration",
00885 ekind_capName (uentry_getKind (e)),
00886 uentry_getName (e)),
00887 uentry_whereLast (e)))
00888 {
00889 uentry_showWhereLast (outer);
00890 }
00891 }
00892 }
00893 }
00894
00895 if (st == globtab && context_getFlag (FLG_NEWDECL))
00896 {
00897 voptgenerror
00898 (FLG_NEWDECL,
00899 message ("New declaration: %q", uentry_getName (e)),
00900 uentry_whereLast (e));
00901 }
00902
00903 eindex = usymtab_addEntryAux (st, e, isSref);
00904 }
00905
00906 exitPoint:
00907 return (staticEntry ? USYMIDINVALID : eindex);
00908 }
00909
00910 # ifndef NOLCL
00911 static void
00912 usymtab_replaceEntryAux ( usymtab st, uentry e)
00913
00914 {
00915 cstring ename = uentry_rawName (e);
00916 int eindex;
00917
00918
00919 eindex = usymtab_getIndex (st, ename);
00920
00921 if (eindex != NOT_FOUND)
00922 {
00923 uentry ce = st->entries[eindex];
00924
00925 if (st->htable != NULL)
00926 {
00927 hashTable_replaceKey (st->htable, uentry_rawName (ce), uentry_rawName (e));
00928 }
00929
00930 uentry_free (ce);
00931 st->entries[eindex] = e;
00932 }
00933 else
00934 {
00935 eindex = usymtab_addEntryAux (st, e, FALSE);
00936 }
00937 }
00938 # endif
00939
00940
00941
00942 void usymtab_supEntry (uentry e)
00943
00944
00945 {
00946 (void) usymtab_supEntryAux (utab, e, FALSE);
00947 }
00948
00949
00950
00951
00952
00953 static uentry
00954 usymtab_supEntryReturnAux ( usymtab tab,
00955 uentry e, bool isref)
00956
00957
00958 {
00959 cstring rawName = cstring_copy (uentry_rawName (e));
00960 bool stat = (tab == globtab) && uentry_isStatic (e);
00961 uentry ret;
00962
00963
00964 (void) usymtab_supEntryAux (tab, e, isref);
00965
00966 if (stat)
00967 {
00968 ret = usymtab_lookupAux (filetab, rawName);
00969 }
00970 else
00971 {
00972 ret = usymtab_lookupAux (tab, rawName);
00973
00974 if (uentry_isInvalid (ret) && usymtab_isDefined (filetab))
00975 {
00976 ret = usymtab_lookupAux (filetab, rawName);
00977 }
00978 }
00979
00980 cstring_free (rawName);
00981 return ret;
00982 }
00983
00984 uentry
00985 usymtab_supEntryReturn ( uentry e)
00986
00987
00988 {
00989 return (usymtab_supEntryReturnAux (utab, e, FALSE));
00990 }
00991
00992 uentry
00993 usymtab_supEntrySrefReturn ( uentry e)
00994
00995
00996 {
00997 return (usymtab_supEntryReturnAux (utab, e, TRUE));
00998 }
00999
01000 uentry
01001 usymtab_supGlobalEntryReturn (uentry e)
01002
01003
01004 {
01005 uentry ret;
01006
01007 ret = usymtab_supEntryReturnAux (globtab, e, FALSE);
01008
01009 if (sRef_modInFunction ())
01010 {
01011 recordFunctionType (ret);
01012 }
01013
01014 return (ret);
01015 }
01016
01017 ctype
01018 usymtab_supTypeEntry ( uentry e)
01019
01020
01021 {
01022 usymId uid;
01023 ctype ret;
01024
01025 if (uentry_isAbstractDatatype (e))
01026 {
01027 uid = usymtab_supAbstractTypeEntry (e, FALSE);
01028 ret = ctype_createAbstract (uid);
01029 }
01030 else
01031 {
01032 uid = usymtab_supEntryAux (globtab, e, FALSE);
01033 ret = ctype_createUser (uid);
01034 }
01035
01036 if (sRef_modInFunction ())
01037 {
01038 recordFunctionType (globtab->entries[uid]);
01039 }
01040
01041 return ret;
01042 }
01043
01044 uentry
01045 usymtab_supReturnTypeEntry ( uentry e)
01046
01047
01048 {
01049 usymId uid;
01050
01051 if (uentry_isAbstractDatatype (e))
01052 {
01053 uid = usymtab_supAbstractTypeEntry (e, FALSE);
01054 }
01055 else
01056 {
01057 uid = usymtab_supEntryAux (globtab, e, FALSE);
01058 }
01059
01060 if (sRef_modInFunction ())
01061 {
01062 recordFunctionType (globtab->entries[uid]);
01063 }
01064
01065 return (globtab->entries[uid]);
01066 }
01067
01068 usymId
01069 usymtab_supAbstractTypeEntry ( uentry e, bool dodef)
01070
01071
01072 {
01073 usymId uid;
01074 uid = usymtab_supEntryAux (globtab, e, FALSE);
01075
01076 if (dodef)
01077 {
01078 uentry ue = usymtab_getTypeEntry (uid);
01079 uentry_setDatatype (ue, uid);
01080 }
01081
01082 if (context_getFlag (FLG_ACCESSMODULE))
01083 {
01084 context_addFileAccessType (uid);
01085 }
01086
01087 if (sRef_modInFunction ())
01088 {
01089 recordFunctionType (globtab->entries[uid]);
01090 }
01091
01092 return (uid);
01093 }
01094
01095 # ifndef NOLCL
01096 usymId
01097 usymtab_supExposedTypeEntry ( uentry e, bool dodef)
01098
01099
01100 {
01101 usymId uid;
01102
01103 uid = usymtab_supEntryAux (globtab, e, FALSE);
01104
01105 if (dodef)
01106 {
01107 uentry ue = usymtab_getTypeEntry (uid);
01108
01109 uentry_setDatatype (ue, uid);
01110 }
01111
01112 if (sRef_modInFunction ())
01113 {
01114 recordFunctionType (globtab->entries[uid]);
01115 }
01116
01117 return (uid);
01118 }
01119 # endif
01120
01121 ctype
01122 usymtab_supForwardTypeEntry ( uentry e)
01123
01124
01125 {
01126 usymId uid = usymtab_supEntryAux (globtab, e, FALSE);
01127 uentry ue = usymtab_getTypeEntry (uid);
01128
01129 uentry_setDatatype (ue, uid);
01130
01131 if (sRef_modInFunction ())
01132 {
01133 recordFunctionType (globtab->entries[uid]);
01134 }
01135
01136 return (uentry_getAbstractType (ue));
01137 }
01138
01139 void
01140 usymtab_supEntrySref (uentry e)
01141
01142
01143 {
01144 sRef old = uentry_getSref (e);
01145
01146
01147 if (sRef_isType (old))
01148 {
01149 uentry ue = usymtab_supEntryReturnAux (utab, e, TRUE);
01150
01151
01152 if (uentry_isValid (ue))
01153 {
01154 sRef uref = uentry_getSref (ue);
01155
01156 sRef_mergeStateQuiet (uref, old);
01157 sRef_clearDerived (uref);
01158 }
01159
01160 }
01161 else if (sRef_isKnown (old))
01162 {
01163 usymtab_supEntry (e);
01164 }
01165 else
01166 {
01167 (void) usymtab_supEntryAux (utab, e, TRUE);
01168 }
01169 }
01170
01171 void usymtab_supGlobalEntry ( uentry e)
01172
01173
01174 {
01175 usymId uid;
01176
01177 DPRINTF (("Sup global entry: %s", uentry_unparse (e)));
01178
01179 uid = usymtab_supEntryAux (globtab, e, FALSE);
01180
01181 if (sRef_modInFunction ())
01182 {
01183 recordFunctionType (globtab->entries[uid]);
01184 }
01185 }
01186
01187 uentry
01188 usymtab_supReturnFileEntry ( uentry e)
01189
01190
01191 {
01192 llassert (filetab != usymtab_undefined);
01193 DPRINTF (("File entry: %s", uentry_unparse (e)));
01194 return (usymtab_supEntryReturnAux (filetab, e, FALSE));
01195 }
01196
01197
01198
01199
01200
01201 bool
01202 usymtab_inDeepScope ()
01203 {
01204 return (utab->lexlevel > paramsScope);
01205 }
01206
01207 static int
01208 usymtab_getIndex ( usymtab s, cstring k)
01209 {
01210 int i;
01211
01212 if (s->htable != NULL)
01213 {
01214 i = hashTable_lookup (s->htable, k);
01215
01216 return i;
01217 }
01218 else
01219 {
01220 for (i = 0; i < s->nentries; i++)
01221 {
01222 uentry current = s->entries[i];
01223
01224 if (!uentry_isUndefined (current)
01225 && cstring_equal (uentry_rawName (current), k))
01226 {
01227 return i;
01228 }
01229 }
01230
01231 return NOT_FOUND;
01232 }
01233 }
01234
01235 static uentry
01236 usymtab_fetchIndex ( usymtab s, int i)
01237 {
01238 llassert (i >= 0 && i < s->nentries);
01239 return (s->entries[i]);
01240 }
01241
01242 usymId
01243 usymtab_getTypeId (cstring k)
01244 {
01245 usymId uid = usymtab_getIndex (globtab, k);
01246
01247 if (uid == NOT_FOUND) return USYMIDINVALID;
01248
01249 if (!(uentry_isDatatype (usymtab_getTypeEntry (uid)))) {
01250 return USYMIDINVALID;
01251 }
01252
01253 return uid;
01254 }
01255
01256 uentry
01257 usymtab_lookupStructTag (cstring k)
01258 {
01259 cstring sname = makeStruct (k);
01260 uentry ue = usymtab_lookupGlob (sname);
01261 cstring_free (sname);
01262 return (ue);
01263 }
01264
01265 uentry
01266 usymtab_lookupUnionTag (cstring k)
01267 {
01268 cstring uname = makeUnion (k);
01269 uentry res = usymtab_lookupGlob (uname);
01270
01271 cstring_free (uname);
01272 return res;
01273 }
01274
01275 uentry
01276 usymtab_lookupEnumTag (cstring k)
01277 {
01278 cstring ename = makeEnum (k);
01279 uentry res = usymtab_lookupGlob (ename);
01280
01281 cstring_free (ename);
01282 return res;
01283 }
01284
01285 usymId
01286 usymtab_getId (cstring k)
01287 {
01288 usymId uid = usymtab_getIndex (globtab, k);
01289 uentry ue;
01290
01291 if (uid == NOT_FOUND)
01292 {
01293 return USYMIDINVALID;
01294 }
01295
01296 ue = usymtab_getGlobalEntry (uid);
01297
01298 if (uentry_isPriv (ue))
01299 {
01300 return USYMIDINVALID;
01301 }
01302
01303 return uid;
01304 }
01305
01306 static uentry
01307 usymtab_getEntryAux ( usymtab s, usymId uid)
01308 {
01309 llassert (uid != USYMIDINVALID);
01310
01311 if (uid < 0 || uid >= s->nentries)
01312 {
01313 llcontbug (message ("usymtab_getEntry: out of range: level = %d [%d]",
01314 s->lexlevel, uid));
01315 return uentry_undefined;
01316 }
01317
01318 llassertprint (uentry_isValid (s->entries[uid]),
01319 ("entry undefined: %d", uid));
01320
01321 return s->entries[uid];
01322 }
01323
01324 uentry
01325 usymtab_getGlobalEntry (usymId uid)
01326
01327 {
01328 if (dbgfree) return (uentry_undefined);
01329
01330 if (utab->lexlevel > paramsScope)
01331 {
01332
01333 return (usymtab_lookupSafe (uentry_rawName (globtab->entries[uid])));
01334 }
01335 else
01336 {
01337 return (globtab->entries[uid]);
01338 }
01339 }
01340
01341 uentry
01342 usymtab_getTypeEntry (usymId uid)
01343
01344 {
01345 if (dbgload)
01346 {
01347 if (uid >= 0 && uid < globtab->nentries)
01348 {
01349 return (globtab->entries[uid]);
01350 }
01351 else
01352 {
01353 return (uentry_undefined);
01354 }
01355 }
01356 else
01357 {
01358 llassert (uid >= 0 && uid < globtab->nentries);
01359
01360 return (globtab->entries[uid]);
01361 }
01362 }
01363
01364
01365
01366
01367
01368 uentry
01369 usymtab_getTypeEntrySafe (usymId uid)
01370
01371 {
01372 if (uid < 0 || uid >= globtab->nentries)
01373 {
01374 return uentry_undefined;
01375 }
01376
01377 return (globtab->entries[uid]);
01378 }
01379
01380 bool
01381 usymtab_isBoolType (usymId uid)
01382
01383 {
01384 llassert (uid >= 0 && uid < globtab->nentries);
01385
01386 return (cstring_equal (uentry_rawName (globtab->entries[uid]),
01387 context_getBoolName ()));
01388 }
01389
01390 cstring
01391 usymtab_getTypeEntryName (usymId uid)
01392
01393 {
01394 uentry ue;
01395
01396 if (dbgfree)
01397 {
01398 return (cstring_makeLiteral ("<freetype>"));
01399 }
01400
01401 ue = usymtab_getTypeEntry (uid);
01402
01403 if (dbgload && !uentry_isValid (ue))
01404 {
01405 return (message ("<missing type: %d>", uid));
01406 }
01407
01408 llassertprint (uentry_isValid (ue), ("type undefined: %d", uid));
01409
01410 return (uentry_getName (ue));
01411 }
01412
01413 static void
01414 usymtab_rehash ( usymtab s)
01415 {
01416 int i;
01417
01418 if (s->htable != NULL)
01419 {
01420 hashTable_free (s->htable);
01421 }
01422
01423 s->htable = hashTable_create (LLHASHSIZE);
01424
01425 for (i = 0; i < s->nentries; i++)
01426 {
01427 hashTable_insert (s->htable, uentry_rawName (s->entries[i]), i);
01428 }
01429 }
01430
01431
01432
01433
01434
01435
01436
01437 static usymtab
01438 usymtab_shallowCopy ( usymtab s)
01439 {
01440 usymtab copytab = usymtab_createRoot ();
01441 int i;
01442
01443 for (i = 0; i < s->nentries; i++)
01444 {
01445 usymtab_addEntryBase (copytab, s->entries[i]);
01446 }
01447
01448 return copytab;
01449 }
01450
01451 static void
01452 usymtab_shallowFree ( usymtab s)
01453 {
01454 aliasTable_free (s->aliases);
01455 refTable_free (s->reftable, s->nentries);
01456 sfree (s->entries);
01457 sfree (s);
01458 }
01459
01460
01461
01462
01463
01464 usymId
01465 usymtab_convertId (usymId uid)
01466
01467 {
01468 uentry ue;
01469 usymId ret;
01470 cstring name;
01471
01472 llassert (usymtab_isDefined (oldtab));
01473
01474 ue = usymtab_getEntryAux (oldtab, uid);
01475
01476 llassertprint (uentry_isValid (ue), ("convertId: undefined: %d", uid));
01477
01478 name = uentry_rawName (ue);
01479
01480 ret = usymtab_getIndex (utab, name);
01481
01482 llassertprint (ret != USYMIDINVALID, ("convertId: return is invalid"));
01483
01484 return (ret);
01485 }
01486
01487 void
01488 usymtab_prepareDump (void)
01489
01490
01491 {
01492 llassert (usymtab_inGlobalScope ());
01493
01494 llassert (oldtab == usymtab_undefined);
01495
01496 oldtab = usymtab_shallowCopy (utab);
01497
01498
01499
01500
01501
01502
01503 qsort (utab->entries, (size_t)utab->nentries,
01504 sizeof (*utab->entries), (int (*)(const void *, const void *)) uentry_xcomparealpha);
01505
01506 usymtab_rehash (utab);
01507 }
01508
01509 void
01510 usymtab_dump (FILE *fout)
01511
01512 {
01513 int i;
01514 bool neednl = FALSE;
01515 uentry lastentry = uentry_undefined;
01516 ekind lastekind = KINVALID;
01517 int linelen = 0;
01518
01519
01520
01521
01522
01523 llassert (oldtab != usymtab_undefined);
01524
01525 for (i = 0; i < utab->nentries; i++)
01526 {
01527 uentry thisentry = utab->entries[i];
01528 ekind thisekind = uentry_getKind (thisentry);
01529
01530
01531 if (uentry_hasRealName (thisentry)) {
01532 if (thisekind != lastekind)
01533 {
01534 if (neednl)
01535 {
01536 check (fputc ('\n', fout) == (int) '\n');
01537 }
01538
01539 neednl = FALSE;
01540 lastentry = uentry_undefined;
01541 fprintf (fout, "*%d (%s)\n", ekind_toInt (thisekind),
01542 cstring_toCharsSafe (ekind_capName (thisekind)));
01543 lastekind = thisekind;
01544 linelen = 0;
01545 }
01546
01547 if (uentry_isInvalid (lastentry) || !uentry_equiv (lastentry, thisentry)
01548 || (linelen > (MAX_DUMP_LINE_LENGTH - (2 * MAX_NAME_LENGTH))))
01549 {
01550 cstring cdump = uentry_dump (thisentry);
01551
01552 lastentry = thisentry;
01553 if (neednl)
01554 {
01555 check (fputc ('\n', fout) == (int) '\n');
01556 linelen = 0;
01557 }
01558
01559 linelen += cstring_length (cdump);
01560
01561
01562 if (cstring_length (cdump) > 0)
01563 {
01564 check (fputs (cstring_toCharsSafe (cdump), fout) != EOF);
01565 }
01566
01567 cstring_free (cdump);
01568 neednl = TRUE;
01569 }
01570 else
01571 {
01572 cstring cdump = uentry_rawName (thisentry);
01573 linelen += cstring_length (cdump);
01574 fprintf (fout, "#%s", cstring_toCharsSafe (cdump));
01575 }
01576 }
01577 }
01578
01579 if (neednl)
01580 {
01581 check (fputc ('\n', fout) == (int) '\n');
01582 }
01583 }
01584
01585 void usymtab_load (FILE *f)
01586
01587
01588 {
01589 char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
01590 char *os = s;
01591 ekind kind = KINVALID;
01592 fileloc loc = g_currentloc;
01593 char c;
01594 uentry ue;
01595
01596 dbgload = TRUE;
01597
01598 llassert (utab == globtab);
01599 llassert (utab->nentries == 0);
01600
01601 while (fgets (s, MAX_DUMP_LINE_LENGTH, f) != NULL
01602 && *s == ';')
01603 {
01604 ;
01605 }
01606
01607 while (s != NULL && *s != ';')
01608 {
01609
01610 if (*s == '*')
01611 {
01612 s++;
01613 kind = ekind_fromInt (getInt (&s));
01614
01615 goto nextiter;
01616 }
01617
01618 if (*s == '$')
01619 {
01620 llfatalerror
01621 (cstring_makeLiteral
01622 ("Library is in obsolete format. Use lclint +whichlib "
01623 "to see which library is being loaded."));
01624 }
01625
01626 ue = uentry_undump (kind, loc, &s);
01627 DPRINTF (("Load: %s", uentry_unparseFull (ue)));
01628
01629 if (uentry_isValid (ue))
01630 {
01631 ue = usymtab_addEntryBase (utab, ue);
01632
01633 }
01634
01635
01636
01637
01638
01639
01640 while (*(s++) == '#')
01641 {
01642 cstring name = cstring_fromCharsO (getWord (&s));
01643 uentry nue = uentry_nameCopy (name, ue);
01644
01645 DPRINTF (("Name copy: %s", uentry_unparseFull (nue)));
01646 usymtab_addEntryBase (utab, nue);
01647 }
01648
01649 while ((c = *s) != '\0' && (c !='\n'))
01650 {
01651 if (c != ' ' || c != '\t')
01652 {
01653 llbuglit ("Junk in load file");
01654 }
01655
01656 s++;
01657 }
01658
01659 nextiter:
01660 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
01661 }
01662
01663 dbgload = FALSE;
01664 sfree (os);
01665 }
01666
01667
01668
01669
01670
01671 void
01672 usymtab_enterFile ()
01673
01674
01675 {
01676 llassert (utab == globtab);
01677
01678 # if 0
01679
01680
01681 usymtab_entries (globtab, ue)
01682 {
01683 if (sRef_hasDerived (uentry_getSref (ue)))
01684 {
01685 fprintf (g_msgstream, "Derived Global: %s\n", uentry_unparse (ue));
01686 fprintf (g_msgstream, "sRef: %s\n", sRef_unparseFull (ue->sref));
01687 }
01688 } end_usymtab_entries ;
01689
01690 # endif
01691
01692 usymtab_enterScope ();
01693 filetab = utab;
01694 }
01695
01696 void
01697 usymtab_exitFile ()
01698
01699
01700 {
01701
01702 llassert (utab->lexlevel == 1);
01703
01704 usymtab_exitScope (exprNode_undefined);
01705 filetab = NULL;
01706 }
01707
01708 void
01709 usymtab_enterScope ()
01710
01711
01712 {
01713 usymtab t = usymtab_create (US_NORMAL, utab, TRUE);
01714
01715
01716 t->aliases = aliasTable_copy (utab->aliases);
01717 utab = t;
01718
01719 llassert (usymtab_isDefined (t->env));
01720
01721 if (t->env->lexlevel == paramsScope && context_inFunctionLike ())
01722 {
01723 noshadowerror = TRUE;
01724 usymtab_handleParams ();
01725 noshadowerror = FALSE;
01726 }
01727 }
01728
01729
01730
01731
01732
01733
01734
01735 static void
01736 usymtab_handleParams (void)
01737
01738
01739 {
01740 usymtab ptab = utab->env;
01741 uentry fcn = context_getHeader ();
01742
01743
01744 usymtab_entries (ptab, param)
01745 {
01746 uentry ue;
01747
01748 if (!uentry_isYield (param))
01749 {
01750 sRef uref;
01751 sRef pref = uentry_getSref (param);
01752
01753 llassertprint (uentry_isAnyParam (param),
01754 ("not param: %s",
01755 uentry_unparseFull (param)));
01756
01757
01758 ue = uentry_makeVariable (fixParamName (uentry_rawName (param)),
01759 uentry_getType (param),
01760 fileloc_copy (uentry_whereDeclared (param)),
01761 FALSE);
01762
01763 uentry_copyState (ue, param);
01764 uentry_setRefParam (ue);
01765
01766 ue = usymtab_supEntrySrefReturn (ue);
01767
01768
01769
01770 if (!sRef_stateKnown (pref))
01771 {
01772 uentry_setDefState (ue, SS_DEFINED);
01773 uentry_setDefState (param, SS_DEFINED);
01774 }
01775 else
01776 {
01777 if (sRef_isStateSpecial (pref))
01778 {
01779 uentry_setDefState (ue, SS_ALLOCATED);
01780 }
01781 else
01782 {
01783 uentry_setDefState (ue, sRef_getDefState (pref));
01784 }
01785 }
01786
01787 uref = uentry_getSref (ue);
01788
01789 if (sRef_isStack (uref))
01790 {
01791 alkind pkind = sRef_getAliasKind (pref);
01792
01793 if (alkind_isKnown (pkind) && !alkind_isLocal (pkind)
01794 && !alkind_isStack (pkind))
01795 {
01796 sRef_setAliasKind (uref, pkind, fileloc_undefined);
01797 sRef_setOrigAliasKind (uref, pkind);
01798 }
01799 else
01800 {
01801 sRef_setAliasKind (uref, AK_IMPTEMP, fileloc_undefined);
01802 sRef_setOrigAliasKind (uref, AK_IMPTEMP);
01803
01804 if (uentry_isOut (param))
01805 {
01806 ;
01807 }
01808 else
01809 {
01810 sRef_setDefined (uref, fileloc_undefined);
01811 }
01812 }
01813
01814 }
01815
01816 usymtab_addMustAlias (uref, pref);
01817
01818 if (!(uentry_isOnly (param) || uentry_isUnique (param)))
01819 {
01820 sRef s = sRef_makeExternal (uref);
01821
01822 usymtab_addMustAlias (uref, s);
01823 }
01824
01825 if (sRef_isKillRef (pref))
01826 {
01827 sRef_setAliasKind (uref, AK_NEWREF, fileloc_undefined);
01828 sRef_setOrigAliasKind (uref, AK_KILLREF);
01829 }
01830 else if (sRef_isRefCounted (uref))
01831 {
01832 sRef_setOrigAliasKind (uref, AK_REFCOUNTED);
01833 }
01834 else
01835 {
01836
01837 sRef_setOrigAliasKind (uref, AK_LOCAL);
01838 }
01839 }
01840 else
01841 {
01842 }
01843 } end_usymtab_entries;
01844
01845
01846 if (uentry_hasSpecialClauses (fcn))
01847 {
01848 specialClauses clauses = uentry_getSpecialClauses (fcn);
01849
01850 specialClauses_preElements (clauses, cl)
01851 {
01852 sRefSet refs = specialClause_getRefs (cl);
01853 sRefMod modf = specialClause_getEntryFunction (cl);
01854
01855
01856 sRefSet_elements (refs, el)
01857 {
01858 sRef base = sRef_getRootBase (el);
01859
01860 if (sRef_isResult (base))
01861 {
01862 ;
01863 }
01864 else if (sRef_isParam (base))
01865 {
01866 if (modf != NULL)
01867 {
01868 sRef sb = sRef_updateSref (el);
01869 sRefSet aliases = usymtab_allAliases (sb);
01870
01871 modf (sb, fileloc_undefined);
01872
01873 sRefSet_elements (aliases, sr)
01874 {
01875 modf (sr, fileloc_undefined);
01876 } end_sRefSet_elements ;
01877
01878 sRefSet_free (aliases);
01879 }
01880 }
01881 else
01882 {
01883 if (sRef_isValid (base))
01884 {
01885 BADBRANCH;
01886 }
01887 }
01888 } end_sRefSet_elements ;
01889 } end_specialClauses_preElements ;
01890 }
01891 }
01892
01893 void
01894 usymtab_enterFunctionScope (uentry fcn)
01895
01896
01897 {
01898 usymtab t = usymtab_create (US_NORMAL, utab, TRUE);
01899
01900 if (utab->lexlevel != fileScope)
01901 {
01902 if (utab->lexlevel > fileScope)
01903 {
01904 llparseerror (cstring_makeLiteral ("New function scope inside function."));
01905
01906 while (utab->lexlevel > fileScope)
01907 {
01908 utab = usymtab_dropEnv (utab);
01909
01910 }
01911
01912 }
01913 else
01914 {
01915 llfatalbug (cstring_makeLiteral ("New function not inside file."));
01916 }
01917 }
01918
01919 globSet_allElements (uentry_getGlobs (fcn), el)
01920 {
01921
01922 if (sRef_isUndefGlob (el))
01923 {
01924 int index = sRef_getScopeIndex (el);
01925 sRef sr = sRef_updateSref (el);
01926 fileloc loc = uentry_whereEarliest (fcn);
01927
01928 if (sRef_isFileStatic (el))
01929 {
01930 ctype ct = sRef_getType (el);
01931 uentry ue;
01932
01933 llassert (usymtab_isDefined (filetab));
01934
01935 ue = usymtab_fetchIndex (filetab, index);
01936
01937 if (ctype_isRealArray (ct) || ctype_isRealSU (ct))
01938 {
01939 sRef_setAllocated (sr, loc);
01940 }
01941 else
01942 {
01943 sRef_setUndefined (sr, loc);
01944 }
01945 }
01946 else
01947 {
01948 uentry ue = globtab->entries[index];
01949 ctype ct = uentry_getType (ue);
01950
01951 if (ctype_isArray (ct) || ctype_isSU (ct))
01952 {
01953 sRef_setAllocated (sr, loc);
01954 }
01955 else
01956 {
01957 sRef_setUndefined (sr, loc);
01958 }
01959 }
01960 }
01961 else if (sRef_isAllocated (el))
01962 {
01963 sRef sr = sRef_updateSref (el);
01964 fileloc loc = uentry_whereEarliest (fcn);
01965
01966 sRef_setAllocated (sr, loc);
01967 }
01968 else if (sRef_isPartial (el))
01969 {
01970 sRef sr = sRef_updateSref (el);
01971 fileloc loc = uentry_whereEarliest (fcn);
01972
01973 sRef_setPartial (sr, loc);
01974 }
01975 else
01976 {
01977 ;
01978 }
01979 } end_globSet_allElements;
01980
01981 utab = t;
01982 }
01983
01984 static void
01985 usymtab_caseBranch (void)
01986
01987 {
01988 usymtab t = usymtab_create (US_CBRANCH, utab, FALSE);
01989 utab = t;
01990 }
01991
01992 void
01993 usymtab_switchBranch ( exprNode s)
01994
01995 {
01996 usymtab t = usymtab_create (US_SWITCH, utab, FALSE);
01997
01998 t->aliases = aliasTable_copy (utab->aliases);
01999 utab = t;
02000 }
02001
02002 void
02003 usymtab_trueBranch ( guardSet guards)
02004
02005 {
02006 usymtab t = usymtab_create (US_TBRANCH, utab, FALSE);
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016 guardSet_free (t->guards);
02017 t->guards = guards;
02018
02019 aliasTable_free (t->aliases);
02020 t->aliases = aliasTable_copy (utab->aliases);
02021
02022 utab = t;
02023 }
02024
02025
02026
02027
02028
02029
02030
02031
02032 void
02033 usymtab_popTrueBranch (exprNode pred, exprNode expr, clause cl)
02034 {
02035
02036
02037
02038
02039
02040
02041 usymtab_altBranch (guardSet_invert (exprNode_getGuards (pred)));
02042 usymtab_popBranches (pred, expr, exprNode_undefined, TRUE, cl);
02043 }
02044
02045 void
02046 usymtab_popCaseBranch ()
02047 {
02048 llassert (utab->kind == US_CBRANCH);
02049 usymtab_quietPlainExitScope ();
02050 }
02051
02052 void
02053 usymtab_popTrueExecBranch (exprNode pred, exprNode expr, clause cl)
02054 {
02055
02056
02057
02058
02059
02060 usymtab_altBranch (guardSet_invert (exprNode_getGuards (pred)));
02061 usymtab_popBranches (pred, expr, exprNode_makeMustExit (), FALSE, cl);
02062 }
02063
02064 void
02065 usymtab_popOrBranch (exprNode pred, exprNode expr)
02066
02067 {
02068 bool mustReturn;
02069 usymtab env = utab->env;
02070 usymtab otab = utab;
02071 int i = 0;
02072
02073 llassert (env != NULL);
02074
02075 if (exprNode_isError (expr))
02076 {
02077 mustReturn = FALSE;
02078 }
02079 else
02080 {
02081 mustReturn = exprNode_mustEscape (expr);
02082 }
02083
02084
02085 llassert (utab->kind == US_TBRANCH);
02086
02087
02088
02089
02090
02091
02092 for (i = 0; i < utab->nentries; i++)
02093 {
02094 uentry current = utab->entries[i];
02095 uentry old = usymtab_lookupAux (env, uentry_rawName (current));
02096
02097 uentry_mergeState (old, current, exprNode_loc (expr),
02098 mustReturn, FALSE, TRUE, ORCLAUSE);
02099 }
02100
02101
02102 if (mustReturn)
02103 {
02104 env->guards = guardSet_levelUnionFree (env->guards,
02105 guardSet_invert (exprNode_getGuards (pred)),
02106 env->lexlevel);
02107 }
02108 else
02109 {
02110 env->aliases = aliasTable_levelUnion (env->aliases, otab->aliases, env->lexlevel);
02111 }
02112
02113
02114 usymtab_quietPlainExitScope ();
02115 }
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125 bool
02126 usymtab_newCase ( exprNode pred, exprNode last)
02127
02128 {
02129 bool mustBreak = usymtab_mustBreak (utab);
02130 bool mustReturn = usymtab_mustEscape (utab);
02131 usymtab stab = utab;
02132
02133
02134
02135
02136
02137 while (stab->kind != US_CBRANCH && stab->kind != US_SWITCH)
02138 {
02139 stab = stab->env;
02140 llassert (stab != GLOBAL_ENV);
02141 }
02142
02143
02144
02145 while (stab->kind == US_CBRANCH)
02146 {
02147 stab = stab->env;
02148 llassert (stab != GLOBAL_ENV);
02149 }
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162 if (!mustBreak && !mustReturn && utab->kind == US_CBRANCH)
02163 {
02164 llassert (stab->kind == US_SWITCH || stab->kind == US_NORMAL);
02165
02166 usymtab_entries (utab, ue)
02167 {
02168 uentry old = usymtab_lookupAux (stab, uentry_rawName (ue));
02169
02170 llassert (uentry_isValid (old));
02171
02172
02173
02174 uentry_mergeState (ue, old, exprNode_loc (last),
02175 FALSE, FALSE, TRUE, CASECLAUSE);
02176 } end_usymtab_entries;
02177
02178 utab->aliases = aliasTable_levelUnion (utab->aliases,
02179 stab->aliases, utab->lexlevel);
02180
02181
02182
02183
02184
02185 return FALSE;
02186 }
02187 else
02188 {
02189 usymtab_caseBranch ();
02190
02191 utab->aliases = aliasTable_copy (stab->aliases);
02192
02193
02194 return TRUE;
02195 }
02196 }
02197
02198
02199
02200
02201
02202 void
02203 usymtab_popAndBranch (exprNode pred, exprNode expr)
02204
02205 {
02206 usymtab env = utab->env;
02207 usymtab otab= utab;
02208 int i = 0;
02209
02210 llassert (utab->kind == US_TBRANCH);
02211
02212
02213
02214
02215
02216
02217 for (i = 0; i < utab->nentries; i++)
02218 {
02219 uentry current = utab->entries[i];
02220 sRef tref = uentry_getSref (current);
02221 uentry old = usymtab_lookupAux (env, uentry_rawName (current));
02222 sRef oref = uentry_getSref (old);
02223
02224
02225
02226
02227 llassert (uentry_isValid (old));
02228 uentry_mergeState (old, current, exprNode_loc (expr),
02229 FALSE, FALSE, TRUE, ANDCLAUSE);
02230
02231
02232
02233
02234
02235 if (sRef_isAnyDefined (tref)
02236 && (sRef_isAllocated (oref) || sRef_isStateUndefined (oref)))
02237 {
02238 sRef_setDefined (oref, g_currentloc);
02239 }
02240 }
02241
02242 utab->guards = guardSet_levelUnionFree (utab->guards,
02243 guardSet_invert (exprNode_getGuards (pred)),
02244 utab->lexlevel);
02245 utab->aliases = aliasTable_levelUnion (utab->aliases, otab->aliases, utab->lexlevel);
02246
02247 usymtab_quietPlainExitScope ();
02248
02249 }
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261 void
02262 usymtab_exitSwitch ( exprNode sw, bool allpaths)
02263
02264 {
02265 usymtab ttab = utab;
02266 usymtab stab = ttab;
02267 usymtab ltab = ttab;
02268 bool lastMustReturn = usymtab_mustEscape (utab);
02269 int i;
02270
02271
02272 while (stab->kind == US_CBRANCH)
02273 {
02274 stab = stab->env;
02275 llassert (stab != GLOBAL_ENV);
02276 }
02277
02278 while (stab->kind == US_NORMAL)
02279 {
02280 stab = stab->env;
02281 llassert (stab != GLOBAL_ENV);
02282 }
02283
02284 llassert (stab->kind == US_SWITCH);
02285
02286
02287 stab = stab->env;
02288 llassert (stab != GLOBAL_ENV);
02289
02290
02291 ttab = ttab->env;
02292 llassert (usymtab_isDefined (ttab));
02293
02294 if (ttab->kind == US_CBRANCH)
02295 {
02296
02297 utab = utab->env;
02298 llassert (utab != GLOBAL_ENV);
02299
02300 while (ttab->kind == US_CBRANCH)
02301 {
02302
02303
02304
02305
02306 bool mustReturn = usymtab_mustEscape (ttab);
02307 bool mustBreak = usymtab_mustBreak (ttab);
02308
02309 usymtab_entries (ttab, current)
02310 {
02311 uentry old = usymtab_lookupAux (ltab, uentry_rawName (current));
02312
02313
02314
02315
02316
02317
02318
02319 if (uentry_isValid (old))
02320 {
02321 if (lastMustReturn)
02322 {
02323 uentry_mergeUses (current, old);
02324 uentry_setState (old, current);
02325 }
02326 else
02327 {
02328 uentry_mergeState (old, current, exprNode_loc (sw),
02329 mustReturn, FALSE, TRUE, SWITCHCLAUSE);
02330 }
02331 }
02332 else
02333 {
02334 ;
02335 }
02336 } end_usymtab_entries;
02337
02338
02339
02340
02341
02342
02343 if (!mustReturn && !mustBreak)
02344 {
02345 usymtab_entries (stab, current)
02346 {
02347 if (usymtab_getIndex (ttab, uentry_rawName (current)) == NOT_FOUND)
02348 {
02349 uentry old =
02350 usymtab_lookupAux (ltab, uentry_rawName (current));
02351
02352
02353 llassert (uentry_isValid (old));
02354 uentry_mergeState (old, current, exprNode_loc (sw),
02355 FALSE, FALSE, TRUE, SWITCHCLAUSE);
02356 }
02357 } end_usymtab_entries;
02358 }
02359
02360 ltab->env = ttab->env;
02361 ttab = ltab->env;
02362
02363
02364
02365
02366
02367 utab = ltab;
02368
02369 lastMustReturn = FALSE;
02370
02371 }
02372 }
02373
02374
02375
02376
02377
02378
02379
02380 for (i = 0; i < ltab->nentries; i++)
02381 {
02382 uentry current = ltab->entries[i];
02383 uentry old = usymtab_lookupAux (stab, uentry_rawName (current));
02384
02385
02386
02387
02388
02389 if (uentry_isValid (old))
02390 {
02391 if (allpaths)
02392 {
02393 uentry_mergeUses (current, old);
02394 uentry_setState (old, current);
02395 }
02396 else
02397 {
02398 uentry_mergeState (old, current, exprNode_loc (sw),
02399 FALSE, FALSE, TRUE, SWITCHCLAUSE);
02400 }
02401 }
02402 else
02403 {
02404 }
02405 }
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416 if (utab->kind == US_SWITCH)
02417 {
02418 usymtab_quietPlainExitScope ();
02419 }
02420 else
02421 {
02422 usymtab_quietPlainExitScope ();
02423 llassert (utab->kind == US_SWITCH);
02424 usymtab_quietPlainExitScope ();
02425 }
02426
02427 }
02428
02429 static void
02430 updateNullState (sRef el, usymtab ttab,
02431 usymtab ftab, bool trueGuard)
02432 {
02433 sRef base = sRef_getRootBase (el);
02434 int level = sRef_lexLevel (base);
02435
02436
02437
02438 if (sRef_isCvar (base))
02439 {
02440 usymId index = sRef_getScopeIndex (base);
02441 uentry ue = usymtab_getRefTab (ttab, level, index);
02442
02443 if (!uentry_isLset (ue))
02444 {
02445 sRef sr = uentry_getSref (ue);
02446
02447 if (trueGuard)
02448 {
02449 sRef_setDerivNullState (sr, el, NS_NOTNULL);
02450 }
02451 else
02452 {
02453 if (!guardSet_isGuarded (ttab->guards, el)
02454 && !sRef_isNotNull (sr))
02455 {
02456 sRef_setDerivNullState (sr, el, NS_DEFNULL);
02457 }
02458 }
02459 }
02460 else
02461 {
02462 }
02463
02464 ue = usymtab_getRefTab (ftab, level, index);
02465
02466 if (!uentry_isLset (ue))
02467 {
02468 sRef sr = uentry_getSref (ue);
02469
02470
02471 if (!trueGuard)
02472 {
02473 sRef_setDerivNullState (sr, el, NS_NOTNULL);
02474 }
02475 else
02476 {
02477
02478 if (!guardSet_isGuarded (ftab->guards, el)
02479 && !sRef_isNotNull (sr))
02480 {
02481 sRef_setDerivNullState (sr, el, NS_DEFNULL);
02482 }
02483 }
02484 }
02485 else
02486 {
02487 }
02488
02489 }
02490
02491 }
02492
02493 void
02494 usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
02495 bool isOpt, clause cl)
02496
02497 {
02498 int i = 0;
02499 usymtab ftab = utab;
02500 usymtab ttab = utab->env;
02501
02502 fileloc loc;
02503 usymtab env;
02504 guardSet guards = exprNode_getGuards (pred);
02505 sRefSet tguards = guardSet_getTrueGuards (guards);
02506 sRefSet fguards = guardSet_getFalseGuards (guards);
02507 bool mustReturnT = exprNode_mustEscape (tbranch);
02508 bool mustReturnF = exprNode_mustEscape (fbranch);
02509
02510 if (exprNode_isDefined (fbranch))
02511 {
02512 loc = exprNode_loc (fbranch);
02513 }
02514 else
02515 {
02516 loc = exprNode_loc (tbranch);
02517 }
02518
02519 llassert (usymtab_isDefined (ttab));
02520
02521 env = ttab->env;
02522
02523 llassert (usymtab_isDefined (env));
02524 llassert (ftab->kind == US_FBRANCH);
02525 llassert (ttab->kind == US_TBRANCH);
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539 sRefSet_allElements (tguards, el)
02540 {
02541 updateNullState (el, ttab, ftab, TRUE);
02542 } end_sRefSet_allElements;
02543
02544 sRefSet_allElements (fguards, el)
02545 {
02546 updateNullState (el, ttab, ftab, FALSE);
02547 } end_sRefSet_allElements;
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557 for (i = 0; i < ftab->nentries; i++)
02558 {
02559 uentry fthis = ftab->entries[i];
02560 uentry old = usymtab_lookupAux (env, uentry_rawName (fthis));
02561 int tindex = usymtab_getIndex (ttab, uentry_rawName (fthis));
02562
02563 if (uentry_isUndefined (old))
02564 {
02565
02566 continue;
02567 }
02568
02569 if (tindex != NOT_FOUND)
02570 {
02571 uentry tthis = ttab->entries[tindex];
02572
02573
02574
02575
02576 if (!mustReturnF)
02577 {
02578 if (!mustReturnT)
02579 {
02580
02581 uentry_mergeState (fthis, tthis, loc,
02582 mustReturnT, FALSE, FALSE, cl);
02583 }
02584 else
02585 {
02586 uentry_mergeUses (fthis, tthis);
02587 }
02588
02589 uentry_setState (old, fthis);
02590
02591
02592 }
02593
02594 else
02595 {
02596 uentry_setState (old, tthis);
02597 uentry_mergeState (old, fthis, loc, mustReturnF,
02598 TRUE, FALSE, cl);
02599 }
02600
02601 ttab->entries[tindex] = uentry_undefined;
02602 uentry_free (tthis);
02603 }
02604 else
02605 {
02606 uentry_mergeState (old, fthis, loc, mustReturnF, TRUE, FALSE, cl);
02607 }
02608 }
02609
02610 for (i = 0; i < ttab->nentries; i++)
02611 {
02612 uentry current = ttab->entries[i];
02613
02614 if (!uentry_isUndefined (current))
02615 {
02616 uentry old = usymtab_lookupAux (env, uentry_rawName (current));
02617
02618 llassertprint (!uentry_isUndefined (old), ("name: <%s>",
02619 uentry_rawName (current)));
02620 if (mustReturnF)
02621 {
02622 uentry_mergeUses (current, old);
02623 uentry_setState (old, current);
02624 }
02625 else
02626 {
02627
02628
02629
02630
02631
02632
02633
02634
02635 uentry_mergeState (old, current, loc, mustReturnT,
02636 FALSE, isOpt, cl);
02637 }
02638 }
02639 }
02640
02641
02642
02643
02644
02645
02646
02647 llassert (NOALIAS (env->aliases, ttab->aliases));
02648 llassert (NOALIAS (env->aliases, ftab->aliases));
02649
02650 aliasTable_free (env->aliases);
02651
02652 env->aliases = aliasTable_levelUnionNew (ttab->aliases,
02653 ftab->aliases, env->lexlevel);
02654
02655 aliasTable_fixSrefs (env->aliases);
02656
02657
02658 usymtab_quietPlainExitScope ();
02659 usymtab_quietPlainExitScope ();
02660
02661 if (mustReturnT)
02662 {
02663 utab->guards = guardSet_levelUnionFree
02664 (utab->guards,
02665 guardSet_invert (exprNode_getGuards (pred)),
02666 utab->lexlevel);
02667 }
02668
02669 if (mustReturnF)
02670 {
02671 utab->guards = guardSet_levelUnion (utab->guards,
02672 exprNode_getGuards (pred),
02673 utab->lexlevel);
02674 }
02675
02676 DPRINTF (("Here."));
02677 }
02678
02679 static void usymtab_fixCases (void) {
02680 while (utab->kind == US_CBRANCH)
02681 {
02682 usymtab_quietPlainExitScope ();
02683 }
02684
02685 llassert (utab->kind != US_CBRANCH);
02686 }
02687
02688 void
02689 usymtab_altBranch ( guardSet guards)
02690
02691 {
02692 usymtab t = usymtab_create (US_FBRANCH, utab, FALSE);
02693 usymtab parent = utab->env;
02694
02695
02696
02697
02698
02699
02700 usymtab_fixCases ();
02701
02702 DPRINTF (("Current kind: %s", usymtab_unparseStack ()));
02703 llassert (utab->kind == US_TBRANCH);
02704 llassert (parent != GLOBAL_ENV);
02705
02706 guardSet_free (t->guards);
02707 t->guards = guards;
02708
02709 aliasTable_free (t->aliases);
02710 t->aliases = aliasTable_copy (parent->aliases);
02711
02712 utab = t;
02713 }
02714
02715 void
02716 usymtab_allDefined (void)
02717
02718 {
02719 int i;
02720
02721 llassert (utab == globtab);
02722
02723 for (i = 0; i < utab->nentries; i++)
02724 {
02725 uentry e = utab->entries[i];
02726
02727 if (uentry_isPriv (e))
02728 {
02729 ;
02730 }
02731 else
02732 {
02733 if (context_getFlag (FLG_SPECUNDECL))
02734 {
02735 fileloc sloc = uentry_whereSpecified (e);
02736 fileloc dloc = uentry_whereDeclared (e);
02737
02738 if (fileloc_isDefined (sloc)
02739 && !uentry_isFakeTag (e)
02740 && !fileloc_isDefined (dloc))
02741 {
02742 voptgenerror
02743 (FLG_SPECUNDECL,
02744 message ("%s %q specified but not declared",
02745 ekind_capName (uentry_getKind (e)),
02746 uentry_getName (e)),
02747 sloc);
02748 }
02749 }
02750
02751 if (!uentry_isCodeDefined (e))
02752 {
02753 fileloc dloc = uentry_whereDeclared (e);
02754
02755 if (fileloc_isLib (dloc))
02756 {
02757 ;
02758 }
02759 else if (fileloc_isDefined (dloc))
02760 {
02761 if (!uentry_isAnyTag (e))
02762 {
02763 if (fileloc_isUser (dloc))
02764 {
02765 voptgenerror
02766 (FLG_DECLUNDEF,
02767 message ("%s %q declared but not defined",
02768 ekind_capName (uentry_getKind (e)),
02769 uentry_getName (e)),
02770 dloc);
02771 }
02772 }
02773 }
02774 else
02775 {
02776 fileloc sloc = uentry_whereSpecified (e);
02777
02778 if (fileloc_isDefined (sloc)
02779 && !fileloc_isImport (sloc)
02780 && !fileloc_isLib (sloc)
02781 && !fileloc_isPreproc (sloc)
02782 && !uentry_isFakeTag (e))
02783 {
02784 if (uentry_isVariable (e) || uentry_isFunction (e))
02785 {
02786 voptgenerror
02787 (FLG_SPECUNDEF,
02788 message ("%s %q specified but not declared or defined",
02789 ekind_capName (uentry_getKind (e)),
02790 uentry_getName (e)),
02791 sloc);
02792 }
02793 else
02794 {
02795 voptgenerror
02796 (FLG_SPECUNDEF,
02797 message ("%s %q specified but not defined",
02798 ekind_capName (uentry_getKind (e)),
02799 uentry_getName (e)),
02800 sloc);
02801 }
02802 }
02803 }
02804 }
02805 }
02806 }
02807 }
02808
02809 void usymtab_exportHeader (void)
02810
02811 {
02812 int i;
02813
02814 for (i = 0; i < utab->nentries; i++)
02815 {
02816 uentry ce = utab->entries[i];
02817
02818 if (!uentry_isDatatype (ce)
02819 && !uentry_isAnyTag (ce)
02820 && !uentry_isEitherConstant (ce) && !uentry_isStatic (ce)
02821 && !uentry_isExternal (ce)
02822 && !uentry_isForward (ce))
02823 {
02824 fileloc fwhere = uentry_whereDeclared (ce);
02825
02826 if (fileloc_isUndefined (fwhere)
02827 && uentry_isFunction (ce))
02828 {
02829 fwhere = uentry_whereDefined (ce);
02830 }
02831
02832 if (fileloc_isDefined (fwhere)
02833 && !fileloc_isHeader (fwhere)
02834 && !(fileloc_isSpecialFile (fwhere)
02835 && !context_getFlag (FLG_UNUSEDSPECIAL)))
02836 {
02837 if (uentry_isVariable (ce))
02838 {
02839 if (optgenerror
02840 (FLG_EXPORTHEADERVAR,
02841 message ("%s %q exported but not declared in header file",
02842 ekind_capName (uentry_getKind (ce)),
02843 uentry_getName (ce)),
02844 fwhere))
02845 {
02846 uentry_showDefSpecInfo (ce, fwhere);
02847 }
02848 }
02849 else
02850 {
02851 if (!uentry_isIter (ce)
02852 && !uentry_isEndIter (ce)
02853 && !uentry_isExpandedMacro (ce))
02854 {
02855 if (uentry_isFunction (ce)
02856 && cstring_equalLit (uentry_rawName (ce), "main"))
02857 {
02858 ;
02859 }
02860 else
02861 {
02862 if (optgenerror
02863 (FLG_EXPORTHEADER,
02864 message ("%s %q exported but not declared "
02865 "in header file",
02866 ekind_capName (uentry_getKind (ce)),
02867 uentry_getName (ce)),
02868 fwhere))
02869 {
02870 uentry_showDefSpecInfo (ce, fwhere);
02871 }
02872 }
02873 }
02874 }
02875 }
02876 }
02877 }
02878 }
02879
02880 void usymtab_exportLocal (void)
02881
02882 {
02883 int i;
02884
02885
02886 for (i = 0; i < utab->nentries; i++)
02887 {
02888 uentry ce = utab->entries[i];
02889
02890
02891 if (!uentry_isDatatype (ce) && !uentry_isAnyTag (ce)
02892 && !uentry_isEitherConstant (ce)
02893 && !uentry_isIter (ce)
02894 && !uentry_isEndIter (ce)
02895 && !uentry_isExpandedMacro (ce)
02896 && uentry_isUsed (ce))
02897 {
02898
02899 filelocList fuses = uentry_getUses (ce);
02900 fileloc mod = uentry_whereDefined (ce);
02901 bool ok = filelocList_isEmpty (fuses);
02902 fileloc fwhere = uentry_whereDeclared (ce);
02903
02904 if (fileloc_isSpecialFile (fwhere)
02905 && !context_getFlag (FLG_UNUSEDSPECIAL))
02906 {
02907 ok = TRUE;
02908 }
02909 else
02910 {
02911 filelocList_elements (fuses, uloc)
02912 {
02913 if (fileloc_isUndefined (uloc) || !fileloc_sameModule (uloc, mod))
02914 {
02915 ok = TRUE;
02916 break;
02917 }
02918 } end_filelocList_elements;
02919 }
02920
02921 if (!ok)
02922 {
02923 if (optgenerror
02924 (FLG_EXPORTLOCAL,
02925 message ("%s exported but not used outside %s: %q",
02926 ekind_capName (uentry_getKind (ce)),
02927 fileloc_getBase (mod),
02928 uentry_getName (ce)),
02929 fwhere))
02930 {
02931 uentry_showDefSpecInfo (ce, fwhere);
02932 }
02933 }
02934 }
02935 }
02936 }
02937
02938 void
02939 usymtab_allUsed (void)
02940
02941 {
02942 int i;
02943 bool isFileStatic = usymtab_inFileScope ();
02944 cstring last_file = cstring_undefined;
02945
02946 for (i = 0; i < utab->nentries; i++)
02947 {
02948 bool hasError = FALSE;
02949 uentry ce = utab->entries[i];
02950 fileloc fwhere = uentry_whereDeclared (ce);
02951
02952 if (fileloc_isUndefined (fwhere))
02953 {
02954 fwhere = uentry_whereDefined (ce);
02955 }
02956
02957 if (fileloc_isInvalid (fwhere)
02958 || fileloc_isLib (fwhere)
02959 || fileloc_isBuiltin (fwhere)
02960 || ((fileloc_isSpecialFile (fwhere)
02961 || fileloc_isSpecialFile (uentry_whereDefined (ce)))
02962 && !context_getFlag (FLG_UNUSEDSPECIAL)))
02963 {
02964 ;
02965 }
02966 else if (!uentry_wasUsed (ce) && !uentry_isAnyTag (ce))
02967 {
02968 cstring fname = fileloc_filename (fwhere);
02969
02970 if (cstring_isUndefined (last_file))
02971 {
02972 last_file = fname;
02973 }
02974 else if (cstring_equal (fname, last_file))
02975 {
02976 }
02977 else
02978 {
02979 cleanupMessages ();
02980 last_file = fname;
02981 }
02982
02983 if (uentry_isParam (ce))
02984 {
02985 if (context_inMacro ())
02986 {
02987 sRef cref = uentry_getSref (ce);
02988
02989 if (uentry_isYield (ce))
02990 {
02991 ;
02992 }
02993 else if (sRef_isSafe (cref))
02994 {
02995 ;
02996 }
02997 else
02998 {
02999 if (uentry_hasRealName (ce))
03000 {
03001 hasError =
03002 optgenerror (FLG_MACROPARAMS,
03003 message ("Macro parameter %q not used",
03004 uentry_getName (ce)),
03005 fwhere);
03006 }
03007 }
03008 }
03009 else
03010 {
03011 if (cstring_equalFree (uentry_getName (ce),
03012 cstring_makeLiteral ("...")))
03013 {
03014 ;
03015 }
03016 else
03017 {
03018 hasError = optgenerror (FLG_PARAMUNUSED,
03019 message ("Parameter %q not used",
03020 uentry_getName (ce)),
03021 fwhere);
03022 }
03023 }
03024 }
03025 else if (uentry_isFunction (ce) || uentry_isIter (ce))
03026 {
03027 if (fileloc_isUser (fwhere))
03028 {
03029 hasError = optgenerror
03030 (FLG_FUNCUNUSED,
03031 message ("%q %q declared but not used",
03032 cstring_makeLiteral
03033 (uentry_isIter (ce) ? "Iterator"
03034 : (isFileStatic ? "File static function" : "Function")),
03035 uentry_getName (ce)),
03036 fwhere);
03037 }
03038 }
03039 else if (uentry_isEndIter (ce))
03040 {
03041 ;
03042 }
03043 else if (uentry_isEnumConstant (ce))
03044 {
03045 if (fileloc_isUser (fwhere))
03046 {
03047 hasError = optgenerror
03048 (FLG_ENUMMEMUNUSED,
03049 message ("Enum member %q not used",
03050 uentry_getName (ce)),
03051 fwhere);
03052 }
03053 }
03054 else if (uentry_isConstant (ce))
03055 {
03056 if (fileloc_isUser (fwhere))
03057 {
03058 hasError = optgenerror
03059 (FLG_CONSTUNUSED,
03060 message ("Constant %q declared but not used",
03061 uentry_getName (ce)),
03062 fwhere);
03063 }
03064 }
03065 else if (uentry_isDatatype (ce))
03066 {
03067 if (fileloc_isUser (fwhere))
03068 {
03069 hasError = optgenerror
03070 (FLG_TYPEUNUSED,
03071 message ("Type %q declared but not used",
03072 uentry_getName (ce)),
03073 fwhere);
03074 }
03075 }
03076 else if (!uentry_isRefParam (ce) && !uentry_isExpandedMacro (ce))
03077 {
03078 llassertprint (uentry_isVar (ce),
03079 ("ce: %s", uentry_unparseFull (ce)));
03080
03081 if (ctype_isFunction (uentry_getType (ce)))
03082 {
03083 if (fileloc_isUser (fwhere))
03084 {
03085 hasError = optgenerror
03086 (FLG_FUNCUNUSED,
03087 message ("%q %q declared but not used",
03088 cstring_makeLiteral
03089 (isFileStatic ? "File static function"
03090 : "Function"),
03091 uentry_getName (ce)),
03092 fwhere);
03093 }
03094 }
03095 else
03096 {
03097 if (fileloc_isUser (fwhere))
03098 {
03099
03100
03101 hasError = optgenerror
03102 (FLG_VARUNUSED,
03103 message ("%q %q declared but not used",
03104 cstring_makeLiteral
03105 (isFileStatic ? "File static variable"
03106 : "Variable"),
03107 uentry_getName (ce)),
03108 fwhere);
03109 }
03110 }
03111 }
03112 else
03113 {
03114 ;
03115 }
03116 }
03117 else if (uentry_isDatatype (ce) || uentry_isAnyTag (ce))
03118 {
03119 ctype ct = uentry_getRealType (ce);
03120
03121
03122 while (ctype_isAP (ct))
03123 {
03124 ct = ctype_getBaseType (ct);
03125 }
03126
03127
03128 if (ctype_isSU (ct))
03129 {
03130 uentryList fields = ctype_getFields (ct);
03131
03132 uentryList_elements (fields, field)
03133 {
03134 if (!uentry_isUsed (field))
03135 {
03136 if (uentry_hasName (ce))
03137 {
03138 hasError |= optgenerror
03139 (FLG_FIELDUNUSED,
03140 message ("Field %q of %s %q declared but not used",
03141 uentry_getName (field),
03142 cstring_makeLiteralTemp
03143 (ctype_isStruct (ct) ? "structure" : "union"),
03144 uentry_getName (ce)),
03145 uentry_whereEarliest (field));
03146 }
03147 else
03148 {
03149 hasError |= optgenerror
03150 (FLG_FIELDUNUSED,
03151 message ("Field %q of unnamed %s declared but not used",
03152 uentry_getName (field),
03153 cstring_makeLiteralTemp
03154 (ctype_isStruct (ct) ? "structure" : "union")),
03155 uentry_whereEarliest (field));
03156 }
03157
03158 uentry_setUsed (field, fileloc_undefined);
03159 }
03160 } end_uentryList_elements;
03161 }
03162 }
03163 else
03164 {
03165 ;
03166 }
03167
03168 if (hasError)
03169 {
03170 if (uentry_isParam (ce) && context_inMacro ())
03171 {
03172 if (fileloc_isDefined (uentry_whereSpecified (ce)))
03173 {
03174 uentry_showWhereSpecified (ce);
03175 }
03176 }
03177 else
03178 {
03179 uentry_showDefSpecInfo (ce, fwhere);
03180 }
03181
03182 uentry_setUsed (ce, fileloc_undefined);
03183 }
03184 }
03185 }
03186
03187 static void
03188 checkGlobalReturn (uentry glob, sRef orig)
03189 {
03190 sRef sr = uentry_getSref (glob);
03191
03192
03193 if (context_getFlag (FLG_GLOBSTATE))
03194 {
03195 if (sRef_isKilledGlob (orig))
03196 {
03197 if (sRef_isStateUndefined (sr)
03198 || sRef_isUnuseable (sr)
03199 || sRef_isStateUnknown (sr)
03200 || sRef_isDead (sr))
03201 {
03202 ;
03203 }
03204 else
03205 {
03206 ctype ct = ctype_realType (uentry_getType (glob));
03207
03208 if (ctype_isVisiblySharable (ct))
03209 {
03210 if (optgenerror
03211 (FLG_GLOBSTATE,
03212 message
03213 ("Killed global %q not released before return",
03214 uentry_getName (glob)),
03215 g_currentloc))
03216 {
03217 sRef_showStateInfo (sr);
03218 }
03219 }
03220 else
03221 {
03222 sRef_protectDerivs ();
03223 (void) checkGlobalDestroyed (sr, g_currentloc);
03224 sRef_clearProtectDerivs ();
03225 }
03226 }
03227 }
03228 else
03229 {
03230 if (sRef_isStateUndefined (sr))
03231 {
03232 if (optgenerror (FLG_GLOBSTATE,
03233 message
03234 ("Function returns with global %q undefined",
03235 uentry_getName (glob)),
03236 g_currentloc))
03237 {
03238 sRef_showStateInfo (sr);
03239 }
03240 }
03241 else
03242 {
03243 if (sRef_isDead (sr))
03244 {
03245 if (optgenerror
03246 (FLG_GLOBSTATE,
03247 message ("Function returns with global %q "
03248 "referencing released storage",
03249 uentry_getName (glob)),
03250 g_currentloc))
03251 {
03252 sRef_showStateInfo (sr);
03253 sRef_setDefState (sr, SS_UNKNOWN, fileloc_undefined);
03254 }
03255 }
03256
03257 if (ctype_isRealPointer (uentry_getType (glob)) &&
03258 sRef_possiblyNull (sr) && !uentry_possiblyNull (glob))
03259 {
03260 if (optgenerror
03261 (FLG_GLOBSTATE,
03262 message ("Function returns with non-null global %q "
03263 "referencing null storage",
03264 uentry_getName (glob)),
03265 g_currentloc))
03266 {
03267 sRef_showNullInfo (sr);
03268 }
03269 }
03270 else
03271 {
03272 checkGlobReturn (glob);
03273 }
03274 }
03275 }
03276 }
03277 }
03278
03279
03280
03281
03282
03283 void usymtab_checkFinalScope (bool isReturn)
03284
03285 {
03286 bool mustFree = context_getFlag (FLG_MUSTFREE);
03287 bool mustDefine = context_getFlag (FLG_MUSTDEFINE);
03288
03289 sRefSet checked = sRefSet_new ();
03290 usymtab stab = utab;
03291 int i;
03292
03293
03294
03295
03296
03297 do
03298 {
03299 for (i = 0; i < stab->nentries; i++)
03300 {
03301 uentry ce = stab->entries[i];
03302 sRef sr = uentry_getSref (ce);
03303 sRef rb = sRef_getRootBase (sr);
03304
03305 if (ctype_isFunction (uentry_getType (ce)))
03306 {
03307 continue;
03308 }
03309
03310 if (mustFree)
03311 {
03312 DPRINTF (("Check entry: %s", uentry_unparseFull (ce)));
03313
03314 if (!sRefSet_member (checked, sr) && !sRef_isGlobal (rb))
03315 {
03316 if (ctype_isRealSU (uentry_getType (ce))
03317 && !uentry_isAnyParam (ce)
03318 && !uentry_isRefParam (ce)
03319 && !uentry_isStatic (ce)
03320 && !sRef_isDependent (sr)
03321 && !sRef_isOwned (sr))
03322 {
03323 sRefSet als = usymtab_allAliases (sr);
03324
03325
03326 if (sRefSet_isEmpty (als))
03327 {
03328 checkLocalDestroyed (sr, g_currentloc);
03329 }
03330 else
03331 {
03332 ;
03333 }
03334
03335 sRefSet_free (als);
03336 }
03337 else if
03338 (!uentry_isStatic (ce)
03339 && ((sRef_isNewRef (sr))
03340 || (((sRef_isOnly (sr) || sRef_isFresh (sr)
03341 || sRef_isKeep (sr) || sRef_isOwned (sr))
03342 && !sRef_isDead (sr))
03343 && (!sRef_definitelyNull (sr))
03344 && (!usymtab_isProbableNull (sr)))))
03345 {
03346 bool hasError = TRUE;
03347
03348
03349
03350
03351
03352
03353 if (!isReturn)
03354 {
03355 if (canLoseReference (sr, g_currentloc))
03356 {
03357 hasError = FALSE;
03358 }
03359 }
03360
03361 if (hasError)
03362 {
03363 if (sRef_hasLastReference (sr))
03364 {
03365 sRef ar = sRef_getAliasInfoRef (sr);
03366
03367 if (optgenerror
03368 (FLG_MUSTFREE,
03369 message
03370 ("Last reference %q to %s storage %qnot %q before %q",
03371 sRef_unparse (sr),
03372 alkind_unparse (sRef_getAliasKind (sr)),
03373 sRef_unparseOpt (ar),
03374 cstring_makeLiteral (sRef_isKeep (sr)
03375 ? "transferred" : "released"),
03376 cstring_makeLiteral (isReturn
03377 ? "return" : "scope exit")),
03378 g_currentloc))
03379 {
03380 sRef_showRefLost (sr);
03381 }
03382 }
03383 else if (sRef_isNewRef (sr))
03384 {
03385 if (optgenerror
03386 (FLG_MUSTFREE,
03387 message
03388 ("%q %q not released before %q",
03389 cstring_makeLiteral
03390 (alkind_isKillRef (sRef_getOrigAliasKind (sr))
03391 ? "Kill reference parameter" : "New reference"),
03392 uentry_getName (ce),
03393 cstring_makeLiteral (isReturn
03394 ? "return" : "scope exit")),
03395 g_currentloc))
03396 {
03397 sRef_showAliasInfo (sr);
03398 }
03399 }
03400 else
03401 {
03402 if (ctype_isRealSU (sRef_getType (sr)))
03403 {
03404 checkStructDestroyed (sr, g_currentloc);
03405 }
03406 else
03407 {
03408 if (optgenerror
03409 (FLG_MUSTFREE,
03410 message
03411 ("%s storage %q not %q before %q",
03412 alkind_capName (sRef_getAliasKind (sr)),
03413 uentry_getName (ce),
03414 cstring_makeLiteral (sRef_isKeep (sr)
03415 ? "transferred" : "released"),
03416 cstring_makeLiteral (isReturn
03417 ? "return" : "scope exit")),
03418 g_currentloc))
03419 {
03420 sRef_showAliasInfo (sr);
03421 }
03422 }
03423 }
03424 }
03425 }
03426 else
03427 {
03428 ;
03429 }
03430 }
03431 else if (mustDefine && uentry_isOut (ce))
03432 {
03433 if (!ynm_toBoolStrict (sRef_isReadable (sr)))
03434 {
03435 voptgenerror
03436 (FLG_MUSTDEFINE,
03437 message ("Out storage %q not defined before %q",
03438 uentry_getName (ce),
03439 cstring_makeLiteral
03440 (isReturn ? "return" : "scope exit")),
03441 g_currentloc);
03442
03443
03444 }
03445 }
03446 else
03447 {
03448 ;
03449 }
03450
03451
03452
03453
03454
03455 if (usymtab_lexicalLevel () > functionScope
03456 && uentry_isVariable (ce)
03457 && (sRef_isLocalVar (sr)
03458 && (sRef_isDependent (sr) || sRef_isLocalState (sr))))
03459 {
03460 sRefSet ab = usymtab_aliasedBy (sr);
03461
03462
03463
03464 if (sRefSet_isEmpty (ab))
03465 {
03466
03467 checkLoseRef (ce);
03468 }
03469 else
03470 {
03471 ;
03472 }
03473
03474 sRefSet_free (ab);
03475 }
03476 else
03477 {
03478 ;
03479 }
03480
03481 checked = sRefSet_insert (checked, sr);
03482 }
03483 }
03484 llassert (usymtab_isDefined (stab->env));
03485
03486 if (usymtab_isBranch (stab))
03487 {
03488 stab = usymtab_dropEnv (stab);
03489 }
03490 else
03491 {
03492 stab = stab->env;
03493 }
03494
03495 llassert (stab != usymtab_undefined);
03496 } while (isReturn && (stab->lexlevel >= paramsScope));
03497
03498 sRefSet_free (checked);
03499
03500
03501
03502
03503
03504
03505
03506
03507 if (isReturn || (utab->lexlevel == paramsScope))
03508 {
03509 uentry fcn = context_getHeader ();
03510 uentryList params = context_getParams ();
03511 globSet uglobs = context_getUsedGlobs ();
03512 globSet sglobs = context_getGlobs ();
03513
03514
03515 if (isReturn && context_maybeSet (FLG_GLOBALIAS))
03516 {
03517 aliasTable_checkGlobs (utab->aliases);
03518 }
03519
03520
03521
03522
03523
03524 if (uentry_hasSpecialClauses (fcn))
03525 {
03526 specialClauses clauses = uentry_getSpecialClauses (fcn);
03527
03528 specialClauses_elements (clauses, cl)
03529 {
03530 if (specialClause_isAfter (cl))
03531 {
03532 sRefTest tst = specialClause_getPostTestFunction (cl);
03533 sRefSet rfs = specialClause_getRefs (cl);
03534
03535 sRefSet_elements (rfs, el)
03536 {
03537 sRef base = sRef_getRootBase (el);
03538
03539 if (sRef_isResult (base))
03540 {
03541 ;
03542 }
03543 else if (sRef_isParam (base))
03544 {
03545 sRef sr = sRef_updateSref (base);
03546 sr = sRef_fixBase (el, sr);
03547
03548 if (tst != NULL && !tst (sr))
03549 {
03550 if (optgenerror
03551 (specialClause_postErrorCode (cl),
03552 message ("%s storage %qcorresponds to "
03553 "storage listed in %q clause",
03554 specialClause_postErrorString (cl, sr),
03555 sRef_unparseOpt (sr),
03556 specialClause_unparseKind (cl)),
03557 g_currentloc))
03558 {
03559 sRefShower ss = specialClause_getPostTestShower (cl);
03560
03561 if (ss != NULL)
03562 {
03563 ss (sr);
03564 }
03565 }
03566 }
03567 }
03568 else
03569 {
03570 if (sRef_isMeaningful (el))
03571 {
03572 BADBRANCH;
03573 }
03574 }
03575 } end_sRefSet_elements ;
03576 }
03577 } end_specialClauses_elements ;
03578 }
03579
03580
03581
03582
03583
03584 uentryList_elements (params, arg)
03585 {
03586 if (!uentry_isElipsisMarker (arg))
03587 {
03588 ctype rt = ctype_realType (uentry_getType (arg));
03589
03590 if (ctype_isMutable (rt) || ctype_isSU (rt))
03591 {
03592 uentry param = usymtab_lookupQuiet (utab, uentry_rawName (arg));
03593 checkParamReturn (param);
03594 }
03595 }
03596 } end_uentryList_elements;
03597
03598 globSet_allElements (sglobs, el)
03599 {
03600 uentry current = sRef_getUentry (el);
03601
03602 if (uentry_isVariable (current) && !uentry_isRealFunction (current))
03603 {
03604 checkGlobalReturn (current, el);
03605 }
03606 } end_globSet_allElements;
03607
03608 globSet_allElements (uglobs, el)
03609 {
03610 if (!globSet_member (sglobs, el))
03611 {
03612 uentry current = sRef_getUentry (el);
03613
03614
03615 if (uentry_isVariable (current)
03616 && !uentry_isRealFunction (current))
03617 {
03618 checkGlobalReturn (current, sRef_undefined);
03619 }
03620 }
03621 } end_globSet_allElements;
03622 }
03623
03624 }
03625
03626 void
03627 usymtab_quietExitScope (fileloc loc)
03628
03629
03630 {
03631 usymtab t = utab->env;
03632
03633 if (utab->reftable != NULL)
03634 {
03635 int i;
03636
03637 for (i = 0; i < utab->nentries; i++)
03638 {
03639 uentry current = utab->entries[i];
03640 uentry old = usymtab_lookupAux (t, uentry_rawName (current));
03641
03642 uentry_mergeState (old, current, loc, FALSE, FALSE, FALSE, NOCLAUSE);
03643 }
03644 }
03645
03646 llassert (t != NULL);
03647
03648 if (t->lexlevel > paramsScope)
03649 {
03650 t->guards = guardSet_levelUnion (t->guards, utab->guards, t->lexlevel);
03651 t->aliases = aliasTable_levelUnionSeq (t->aliases, utab->aliases,
03652 t->lexlevel);
03653 utab->aliases = aliasTable_undefined;
03654 }
03655
03656 t->mustBreak = utab->mustBreak;
03657 t->exitCode = utab->exitCode;
03658
03659 usymtab_freeLevel (utab);
03660
03661 utab = t;
03662 }
03663
03664
03665
03666
03667
03668
03669 void usymtab_quietPlainExitScope (void)
03670
03671
03672 {
03673 usymtab t = utab->env;
03674
03675 llassert (t != NULL);
03676 llassert (NOALIAS (utab->aliases, t->aliases));
03677 usymtab_freeLevel (utab);
03678 utab = t;
03679 }
03680
03681 void usymtab_exitScope (exprNode expr)
03682
03683
03684 {
03685 usymtab ctab = usymtab_undefined;
03686 usymtab lctab = usymtab_undefined;
03687 bool mustReturn = exprNode_mustEscape (expr);
03688
03689 if (utab->kind == US_CBRANCH)
03690 {
03691
03692
03693
03694
03695 ctab = utab;
03696
03697 while (utab->kind == US_CBRANCH)
03698 {
03699 lctab = utab;
03700 utab = utab->env;
03701 llassert (utab != GLOBAL_ENV);
03702 }
03703 }
03704
03705 if (utab->kind == US_TBRANCH || utab->kind == US_FBRANCH
03706 || utab->kind == US_CBRANCH || utab->kind == US_SWITCH) {
03707
03708 if (context_inMacro ()) {
03709
03710
03711
03712 llerror (FLG_SYNTAX, message ("Problem parsing macro body of %s (unbalanced scopes). Attempting to recover, recommend /*@notfunction@*/ before macro definition.",
03713 context_inFunctionName ()));
03714
03715 while (utab->kind == US_TBRANCH
03716 || utab->kind == US_FBRANCH
03717 || utab->kind == US_CBRANCH
03718 || utab->kind == US_SWITCH)
03719 {
03720 utab = utab->env;
03721 llassert (utab != GLOBAL_ENV);
03722 }
03723 } else {
03724 llcontbug (("exitScope: in branch: %s", usymtab_unparseStack ()));
03725
03726 }
03727 }
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739 llassertfatal (utab->env != GLOBAL_ENV);
03740
03741 if (utab->env->kind != US_SWITCH)
03742 {
03743 usymtab_allUsed ();
03744 }
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755 if (!mustReturn && (usymtab_lexicalLevel () > functionScope))
03756 {
03757
03758
03759
03760
03761 usymtab_checkFinalScope (FALSE);
03762 }
03763
03764 if (usymtab_lexicalLevel () == paramsScope && context_inFunctionLike ())
03765 {
03766
03767
03768
03769
03770 uentryList params = context_getParams ();
03771 globSet globs = context_getUsedGlobs ();
03772
03773
03774 uentryList_elements (params, ue)
03775 {
03776 uentry_fixupSref (ue);
03777 } end_uentryList_elements;
03778
03779 clearFunctionTypes ();
03780
03781
03782 globSet_allElements (globs, el)
03783 {
03784 if (sRef_isCvar (el))
03785 {
03786 uentry current;
03787 int index = sRef_getScopeIndex (el);
03788
03789 if (sRef_isFileStatic (el))
03790 {
03791 llassert (usymtab_isDefined (filetab));
03792 current = usymtab_fetchIndex (filetab, index);
03793 }
03794 else
03795 {
03796 current = usymtab_fetchIndex (globtab, index);
03797 }
03798
03799 if (uentry_isVariable (current))
03800 {
03801 uentry_fixupSref (current);
03802 }
03803 else
03804 {
03805 sRef_clearDerived (uentry_getSref (current));
03806 }
03807 }
03808 } end_globSet_allElements;
03809 }
03810
03811 usymtab_quietExitScope (exprNode_loc (expr));
03812
03813 if (lctab != usymtab_undefined)
03814 {
03815 lctab->env = utab;
03816 utab = ctab;
03817 }
03818
03819 }
03820
03821
03822
03823
03824
03825
03826 int
03827 uentry_directParamNo (uentry ue)
03828 {
03829 if (uentry_isVar (ue))
03830 {
03831 sRef sr = uentry_getSref (ue);
03832
03833 if (sRef_lexLevel (sr) == functionScope)
03834 {
03835
03836 int index = sr->info->cvar->index;
03837
03838
03839 if (index < uentryList_size (context_getParams ()))
03840 {
03841 return index;
03842 }
03843 }
03844 }
03845 return -1;
03846 }
03847
03848 uentry
03849 usymtab_getParam (int paramno)
03850
03851 {
03852
03853
03854
03855
03856
03857
03858
03859 usymtab s = utab;
03860
03861 if (!context_inFunctionLike ())
03862 llfatalbug (message ("usymtab_getParam: not in function context: %q",
03863 context_unparse ()));
03864
03865 while (s->lexlevel > paramsScope)
03866 {
03867 s = s->env;
03868 }
03869
03870 llassert (usymtab_isDefined (s));
03871
03872 if (paramno >= s->nentries)
03873 {
03874
03875
03876
03877
03878 uentry err = uentry_makeVariableLoc (cstring_makeLiteralTemp ("<error>"),
03879 ctype_unknown);
03880
03881 uentry_markOwned (err);
03882 return (err);
03883 }
03884
03885 return (s->entries[paramno]);
03886 }
03887
03888 static uentry
03889 usymtab_getRefTab ( usymtab u, int level, usymId index)
03890 {
03891 uentry ue;
03892
03893
03894 ue = usymtab_getRefNoisy (u, level, index);
03895
03896
03897 if (uentry_isUndefined (ue))
03898 {
03899 llbug (message ("usymtab_getRef: out of range: %d. level = %d",
03900 index, level));
03901 }
03902
03903
03904 return ue;
03905 }
03906
03907 static usymtab
03908 usymtab_dropEnv ( usymtab s)
03909 {
03910 if (s->kind == US_CBRANCH)
03911 {
03912 usymtab t = s;
03913
03914 do
03915 {
03916 t = s;
03917 s = s->env;
03918 llassert (s != GLOBAL_ENV);
03919 } while (s->kind == US_CBRANCH);
03920
03921
03922 s = t;
03923 llassert (s != GLOBAL_ENV);
03924 }
03925
03926 if (s->kind == US_FBRANCH)
03927 {
03928 s = s->env;
03929 llassert (usymtab_isDefined (s));
03930 llassert (s->kind == US_TBRANCH);
03931 }
03932
03933 llassert (s != GLOBAL_ENV);
03934 s = s->env;
03935
03936 return s;
03937 }
03938
03939 uentry
03940 usymtab_getRefQuiet (int level, usymId index)
03941
03942 {
03943 usymtab s = utab;
03944
03945
03946 llassert (s != NULL);
03947 llassert (index >= 0);
03948
03949 if (level > s->lexlevel)
03950 {
03951
03952 return uentry_undefined;
03953 }
03954
03955 llassertprint (level <= s->lexlevel, ("level: %d / lexlevel: %d",
03956 level, s->lexlevel));
03957
03958 while (s->lexlevel > level)
03959 {
03960 if (usymtab_isBranch (s))
03961 {
03962 int eindex = refTable_lookup (s, level, index);
03963
03964 if (eindex != NOT_FOUND)
03965 {
03966 return (s->entries[eindex]);
03967 }
03968 }
03969
03970 s = usymtab_dropEnv (s);
03971 }
03972
03973 while (usymtab_isBranch (s) && s->lexlevel == level)
03974 {
03975 int eindex = refTable_lookup (s, level, index);
03976
03977 if (eindex != NOT_FOUND)
03978 {
03979 return (s->entries[eindex]);
03980 }
03981
03982 s = usymtab_dropEnv (s);
03983 }
03984
03985 if (index >= s->nentries)
03986 {
03987 return uentry_undefined;
03988 }
03989
03990 llassert (!uentry_isUndefined (s->entries[index]));
03991
03992 return s->entries[index];
03993 }
03994
03995 static uentry
03996 usymtab_getRefNoisy ( usymtab s, int level, usymId index)
03997 {
03998 usymtab otab = s;
03999 uentry ue = uentry_undefined;
04000
04001
04002 llassert (index >= 0);
04003
04004
04005 while (s->lexlevel > level)
04006 {
04007
04008 if (usymtab_isBranch (s))
04009 {
04010 int eindex = refTable_lookup (s, level, index);
04011
04012 if (eindex != NOT_FOUND)
04013 {
04014 ue = s->entries[eindex];
04015
04016 if (s != otab)
04017 {
04018 while (!usymtab_isBranch (otab))
04019 {
04020 otab = usymtab_dropEnv (otab);
04021 llassert (otab != GLOBAL_ENV);
04022 }
04023
04024 if (refTable_lookup (otab, level, index) == NOT_FOUND)
04025 {
04026 ue = usymtab_addRefEntry (otab, uentry_rawName (ue));
04027 }
04028 else
04029 {
04030 ;
04031 }
04032 }
04033
04034 return ue;
04035 }
04036 }
04037
04038 s = usymtab_dropEnv (s);
04039 }
04040
04041 llassert (usymtab_isDefined (s));
04042
04043 while (usymtab_isBranch (s) && s->lexlevel == level)
04044 {
04045 int eindex = refTable_lookup (s, level, index);
04046
04047
04048 if (eindex != NOT_FOUND)
04049 {
04050 ue = s->entries[eindex];
04051
04052 if (s != otab)
04053 {
04054 while (!usymtab_isBranch (otab))
04055 {
04056 otab = usymtab_dropEnv (otab);
04057 llassert (otab != GLOBAL_ENV);
04058 }
04059
04060 ue = usymtab_addRefEntry (otab, uentry_rawName (ue));
04061 }
04062 else
04063 {
04064 ;
04065 }
04066
04067 return ue;
04068 }
04069
04070 s = usymtab_dropEnv (s);
04071 }
04072
04073 if (s->lexlevel == level && (index < s->nentries))
04074 {
04075 ue = s->entries[index];
04076
04077 if (uentry_isValid (ue))
04078 {
04079 if (s != otab)
04080 {
04081 while (!usymtab_isBranch (otab))
04082 {
04083 otab = usymtab_dropEnv (otab);
04084
04085 if (otab == GLOBAL_ENV)
04086 {
04087 return ue;
04088 }
04089 }
04090
04091 ue = usymtab_addRefEntry (otab, uentry_rawName (ue));
04092 }
04093 else
04094 {
04095 }
04096 }
04097
04098 return ue;
04099 }
04100
04101
04102 if (index >= s->nentries)
04103 {
04104 return uentry_undefined;
04105 }
04106
04107 llassert (!uentry_isUndefined (s->entries[index]));
04108
04109 return s->entries[index];
04110 }
04111
04112
04113
04114
04115
04116
04117
04118
04119 static
04120 int refTable_lookup ( usymtab ut, int level, int index)
04121 {
04122 refTable rt = ut->reftable;
04123 int i;
04124
04125 llassert (rt != NULL);
04126
04127
04128 for (i = 0; i < ut->nentries; i++)
04129 {
04130 if (rt[i]->level == level && rt[i]->index == index)
04131 {
04132 return i;
04133 }
04134 }
04135
04136 return NOT_FOUND;
04137 }
04138
04139 static
04140 refentry refentry_create (int level, int index)
04141 {
04142 refentry r = (refentry) dmalloc (sizeof (*r));
04143
04144 r->level = level;
04145 r->index = index;
04146
04147 return r;
04148 }
04149
04150 static uentry
04151 usymtab_addRefEntry ( usymtab s, cstring k)
04152 {
04153 int eindex;
04154 usymtab ut = s;
04155
04156 llassert (ut->reftable != NULL);
04157
04158 while (s != GLOBAL_ENV)
04159 {
04160 eindex = usymtab_getIndex (s, k);
04161
04162 if (eindex != NOT_FOUND)
04163 {
04164 uentry current = s->entries[eindex];
04165
04166 if (uentry_isVar (current) && !ctype_isFunction (uentry_getType (current)))
04167 {
04168 uentry ue;
04169
04170 DPRINTF (("Here: copying %s", uentry_unparseFull (current)));
04171
04172 ue = uentry_copy (current);
04173
04174 DPRINTF (("Here: copying %s", uentry_unparseFull (ue)));
04175
04176 usymtab_addEntryQuiet (ut, ue);
04177
04178 if (s->reftable != NULL)
04179 {
04180 refentry ref = s->reftable[eindex];
04181
04182
04183 ut->reftable[ut->nentries - 1]
04184 = refentry_create (ref->level, ref->index);
04185 }
04186 else
04187 {
04188 ut->reftable[ut->nentries - 1]
04189 = refentry_create (s->lexlevel, eindex);
04190 }
04191
04192 return (ue);
04193 }
04194 else
04195 {
04196 return (current);
04197 }
04198 }
04199
04200 s = usymtab_dropEnv (s);
04201 }
04202
04203 return uentry_undefined;
04204 }
04205
04206 static uentry usymtab_lookupAux (usymtab s, cstring k)
04207 {
04208 DPRINTF (("Lookup: %s", k));
04209
04210 while (s != GLOBAL_ENV)
04211 {
04212 int eindex = usymtab_getIndex (s, k);
04213
04214 if (eindex != NOT_FOUND)
04215 {
04216 uentry ret = s->entries[eindex];
04217
04218 DPRINTF (("Found: %s", uentry_unparseFull (ret)));
04219 return (ret);
04220 }
04221
04222 if (s->kind == US_TBRANCH || s->kind == US_FBRANCH
04223 || s->kind == US_CBRANCH)
04224 {
04225 uentry ret = usymtab_addRefEntry (s, k);
04226 DPRINTF (("Ref entry: %s", uentry_unparseFull (ret)));
04227 return ret;
04228 }
04229
04230 s = s->env;
04231 }
04232
04233 return uentry_undefined;
04234 }
04235
04236 static uentry
04237 usymtab_lookupQuiet (usymtab s, cstring k)
04238 {
04239 int eindex;
04240
04241 while (s != GLOBAL_ENV)
04242 {
04243 eindex = usymtab_getIndex (s, k);
04244
04245 if (eindex != NOT_FOUND)
04246 {
04247 uentry ret = s->entries[eindex];
04248 return (ret);
04249 }
04250
04251 s = s->env;
04252 }
04253
04254 return uentry_undefined;
04255 }
04256
04257 uentry
04258 usymtab_lookupSafe (cstring k)
04259
04260 {
04261 DPRINTF (("Lookup safe: %s", k));
04262 return (usymtab_lookupAux (utab, k));
04263 }
04264
04265 uentry
04266 usymtab_lookupExpose (cstring k)
04267
04268 {
04269 uentry ce = usymtab_lookupAux (utab, k);
04270
04271 if (uentry_isUndefined (ce))
04272 {
04273 llfatalbug (message ("usymtab_lookup: not found: *%s*", k));
04274 }
04275
04276 if (uentry_isPriv (ce))
04277 {
04278 llfatalbug (message ("usymtab_lookup: private: *%s*", k));
04279 }
04280
04281 return ce;
04282 }
04283
04284 uentry usymtab_lookupExposeGlob (cstring k)
04285 {
04286 return (usymtab_lookupGlobSafe (k));
04287 }
04288
04289 uentry usymtab_lookupGlob (cstring k)
04290
04291 {
04292 uentry ce = usymtab_lookupAux (globtab, k);
04293
04294 if (uentry_isUndefined (ce))
04295 llfatalbug (message ("usymtab_lookup: not found: %s", k));
04296
04297 if (uentry_isPriv (ce))
04298 llfatalbug (message ("usymtab_lookup: private: %s", k));
04299
04300 return ce;
04301 }
04302
04303 uentry
04304 usymtab_lookupGlobSafe (cstring k)
04305
04306 {
04307 uentry ce = usymtab_lookupAux (globtab, k);
04308
04309 return ce;
04310 }
04311
04312 uentry usymtab_lookupEither (cstring k)
04313
04314 {
04315 uentry ce = usymtab_lookupSafe (k);
04316
04317 if (uentry_isUndefined (ce))
04318 llfatalerror (message ("usymtab_lookup: not found: %s", k));
04319
04320 return ce;
04321 }
04322
04323 # ifndef NOLCL
04324 ctype
04325 usymtab_lookupType (cstring k)
04326
04327 {
04328 usymId uid = usymtab_getTypeId (k);
04329
04330 if (uid == USYMIDINVALID)
04331 {
04332 llcontbug (message ("usymtab_lookupType: not found: %s", k));
04333 return ctype_unknown;
04334 }
04335
04336 return (uentry_getRealType (usymtab_getTypeEntry (uid)));
04337 }
04338 # endif
04339
04340 ctype
04341 usymtab_lookupAbstractType (cstring k)
04342 {
04343 usymId uid = usymtab_getTypeId (k);
04344
04345 if (uid == USYMIDINVALID)
04346 {
04347 llcontbug (message ("usymtab_lookupType: not found: %s", k));
04348 return ctype_unknown;
04349 }
04350
04351 return (uentry_getAbstractType (usymtab_getTypeEntry (uid)));
04352 }
04353
04354
04355
04356
04357
04358
04359
04360 ctype
04361 usymtab_structFieldsType (uentryList f)
04362
04363 {
04364 return (usymtab_suFieldsType (f, TRUE));
04365 }
04366
04367 ctype
04368 usymtab_unionFieldsType (uentryList f)
04369
04370 {
04371 return (usymtab_suFieldsType (f, FALSE));
04372 }
04373
04374 static ctype
04375 usymtab_suFieldsType (uentryList f, bool isStruct)
04376
04377 {
04378 int i;
04379
04380 if (fileloc_isSpec (g_currentloc)) return (ctype_undefined);
04381
04382 for (i = 0; i < globtab->nentries; i++)
04383 {
04384 uentry current = globtab->entries[i];
04385
04386 if ((isStruct
04387 ? uentry_isStructTag (current) : uentry_isUnionTag (current)))
04388 {
04389 if (isFakeTag (uentry_rawName (current)))
04390 {
04391 ctype ct = uentry_getType (current);
04392
04393 if ((isStruct ? ctype_isStruct (ct) : ctype_isUnion (ct))
04394 && (uentryList_matchFields (f, ctype_getFields (ct))))
04395 {
04396 return uentry_getAbstractType (current);
04397 }
04398 }
04399 }
04400 }
04401
04402 return ctype_undefined;
04403 }
04404
04405 ctype
04406 usymtab_enumEnumNameListType (enumNameList f)
04407
04408 {
04409 int i;
04410
04411 for (i = 0; i < globtab->nentries; i++)
04412 {
04413 uentry current = globtab->entries[i];
04414
04415 if (uentry_isEnumTag (current))
04416 {
04417 if (isFakeTag (uentry_rawName (current)))
04418 {
04419 ctype ct = uentry_getType (current);
04420
04421 if (ctype_isEnum (ct) && (enumNameList_match (f, ctype_elist (ct))))
04422 {
04423 return uentry_getType (current);
04424 }
04425 }
04426 }
04427 }
04428
04429 return ctype_undefined;
04430 }
04431
04432 bool
04433 usymtab_exists (cstring k)
04434
04435 {
04436 uentry ce = usymtab_lookupSafe (k);
04437
04438 return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
04439 }
04440
04441 bool
04442 usymtab_existsReal (cstring k)
04443
04444 {
04445 uentry ce = usymtab_lookupSafe (k);
04446
04447 return (!(uentry_isUndefined (ce))
04448 && !(uentry_isPriv (ce))
04449 && !(uentry_isExpandedMacro (ce)));
04450 }
04451
04452 bool
04453 usymtab_existsGlob (cstring k)
04454
04455 {
04456 uentry ce = usymtab_lookupAux (globtab, k);
04457
04458 return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
04459 }
04460
04461 # ifndef NOLCL
04462 bool
04463 usymtab_existsEither (cstring k)
04464
04465 {
04466 uentry ce = usymtab_lookupAux (utab, k);
04467
04468 return (uentry_isValid (ce));
04469 }
04470
04471 bool
04472 usymtab_existsGlobEither (cstring k)
04473
04474 {
04475 uentry ce = usymtab_lookupAux (globtab, k);
04476
04477 return (uentry_isValid (ce));
04478 }
04479 # endif
04480
04481 bool
04482 usymtab_existsType (cstring k)
04483
04484 {
04485 uentry ce = usymtab_lookupAux (globtab, k);
04486
04487 return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)) && uentry_isDatatype (ce));
04488 }
04489
04490 bool
04491 usymtab_existsTypeEither (cstring k)
04492
04493 {
04494 uentry ce = usymtab_lookupAux (globtab, k);
04495
04496 return (uentry_isValid (ce) && uentry_isDatatype (ce));
04497 }
04498
04499 bool
04500 usymtab_existsStructTag (cstring k)
04501 {
04502 cstring sname = makeStruct (k);
04503 uentry ce = usymtab_lookupAux (globtab, sname);
04504
04505 cstring_free (sname);
04506
04507
04508 return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
04509 }
04510
04511 bool
04512 usymtab_existsUnionTag (cstring k)
04513 {
04514 cstring uname = makeUnion (k);
04515 uentry ce = usymtab_lookupAux (globtab, uname);
04516
04517 cstring_free (uname);
04518
04519 return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
04520 }
04521
04522 bool
04523 usymtab_existsEnumTag (cstring k)
04524 {
04525 cstring ename = makeEnum (k);
04526 uentry ce = usymtab_lookupAux (globtab, ename);
04527
04528 cstring_free (ename);
04529 return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
04530 }
04531
04532 # ifndef NOLCL
04533 bool usymtab_existsVar (cstring k)
04534
04535 {
04536 uentry ce = usymtab_lookupSafe (k);
04537
04538 return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)) && (uentry_isVar (ce)));
04539 }
04540 # endif
04541
04542
04543
04544
04545
04546 static void
04547 refTable_free ( refTable x, int nentries)
04548 {
04549 if (x != NULL)
04550 {
04551 int i;
04552
04553 for (i = 0; i < nentries; i++)
04554 {
04555 sfree (x[i]);
04556 }
04557
04558 sfree (x);
04559 }
04560 }
04561
04562 static void
04563 usymtab_freeLevel ( usymtab u)
04564
04565 {
04566 int i;
04567
04568 aliasTable_free (u->aliases);
04569
04570 refTable_free (u->reftable, u->nentries);
04571
04572 if (u == filetab || u == globtab)
04573 {
04574 for (i = 0; i < u->nentries; i++)
04575 {
04576 uentry_freeComplete (u->entries[i]);
04577 }
04578 }
04579 else
04580 {
04581 for (i = 0; i < u->nentries; i++)
04582 {
04583 uentry_free (u->entries[i]);
04584 }
04585 }
04586
04587 guardSet_free (u->guards);
04588 sfree (u->entries);
04589
04590 if (u != globtab
04591 && u != utab
04592 && u != filetab)
04593 {
04594 llassert (u->htable == NULL);
04595 sfree (u);
04596 }
04597
04598
04599 }
04600
04601 static void
04602 usymtab_freeAux ( usymtab u)
04603
04604
04605 {
04606 while (u != GLOBAL_ENV)
04607 {
04608 usymtab t = u->env;
04609 usymtab_freeLevel (u);
04610 u = t;
04611
04612 }
04613
04614 }
04615
04616 void usymtab_free ()
04617
04618
04619 {
04620 dbgfree = TRUE;
04621 usymtab_freeAux (utab);
04622 }
04623
04624 static int usymtab_lexicalLevel (void)
04625 {
04626 return (utab->lexlevel);
04627 }
04628
04629 bool usymtab_inGlobalScope ()
04630 {
04631 return (utab == globtab);
04632 }
04633
04634 bool usymtab_inFileScope ()
04635 {
04636 return (utab->lexlevel == fileScope);
04637 }
04638
04639 bool usymtab_inFunctionScope ()
04640 {
04641 return (utab->lexlevel == functionScope);
04642 }
04643
04644 # ifndef NOLCL
04645 void
04646 usymtab_replaceEntry (uentry s)
04647
04648
04649 {
04650 usymtab_replaceEntryAux (utab, s);
04651 }
04652 # endif
04653
04654 bool
04655 usymtab_matchForwardStruct (usymId u1, usymId u2)
04656
04657 {
04658 uentry ue1 = usymtab_getTypeEntry (u1);
04659 uentry ue2 = usymtab_getTypeEntry (u2);
04660
04661 if (uentry_isAnyTag (ue2))
04662 {
04663 ctype reptype = uentry_getType (ue1);
04664
04665 if (ctype_isPointer (reptype))
04666 {
04667 ctype repbase = ctype_getBaseType (reptype);
04668
04669 if (ctype_isUA (repbase))
04670 {
04671 typeId rtuid = ctype_typeId (repbase);
04672
04673 if (u2 == rtuid) return TRUE;
04674
04675 if (usymId_isValid (rtuid))
04676 {
04677 reptype = uentry_getType (usymtab_getTypeEntry (rtuid));
04678
04679 return (ctype_isUA (reptype) && (u2 == (ctype_typeId (reptype))));
04680 }
04681 }
04682 }
04683 }
04684
04685 return FALSE;
04686 }
04687
04688 void usymtab_addGuards (guardSet guards)
04689
04690 {
04691 utab->guards = guardSet_union (utab->guards, guards);
04692 }
04693
04694 static bool usymtab_isGuardedAux (sRef s)
04695
04696 {
04697 usymtab tab = utab;
04698 sRef base = sRef_getRootBase (s);
04699 int lowlevel = paramsScope;
04700 int baselevel = sRef_lexLevel (base);
04701
04702 if (sRef_isCvar (base))
04703 {
04704 lowlevel = baselevel;
04705 if (lowlevel < paramsScope) lowlevel = paramsScope;
04706 }
04707
04708 while (tab->lexlevel >= lowlevel)
04709 {
04710 if (guardSet_isGuarded (tab->guards, s))
04711 {
04712
04713
04714
04715
04716
04717
04718 return TRUE;
04719 }
04720
04721 tab = usymtab_dropEnv (tab);
04722 }
04723
04724 return FALSE;
04725 }
04726
04727 void usymtab_unguard (sRef s)
04728 {
04729 usymtab tab = utab;
04730 sRef base = sRef_getRootBase (s);
04731 int lowlevel = paramsScope;
04732 int baselevel = sRef_lexLevel (base);
04733
04734 if (sRef_isCvar (base))
04735 {
04736 lowlevel = baselevel;
04737 if (lowlevel < paramsScope) lowlevel = paramsScope;
04738 }
04739
04740 while (tab->lexlevel >= lowlevel)
04741 {
04742 if (guardSet_isGuarded (tab->guards, s))
04743 {
04744 guardSet_delete (tab->guards, s);
04745 }
04746
04747 tab = usymtab_dropEnv (tab);
04748 }
04749 }
04750
04751 bool usymtab_isGuarded (sRef s)
04752 {
04753
04754 return (sRef_aliasCompleteSimplePred (usymtab_isGuardedAux, s));
04755 }
04756
04757 bool usymtab_isProbableNull (sRef s)
04758 {
04759 return (sRef_aliasCheckSimplePred (usymtab_isProbableNullAux, s));
04760 }
04761
04762 bool usymtab_isProbableDeepNull (sRef s)
04763 {
04764 return (sRef_deepPred (usymtab_isProbableNull, s));
04765 }
04766
04767 static bool usymtab_isProbableNullAux (sRef s)
04768
04769 {
04770 usymtab tab = utab;
04771 sRef base = sRef_getRootBase (s);
04772 int lowlevel = paramsScope;
04773
04774 if (sRef_isCvar (base))
04775 {
04776 lowlevel = sRef_lexLevel (base);
04777 if (lowlevel < paramsScope) lowlevel = paramsScope;
04778 }
04779
04780 while (tab->lexlevel >= lowlevel)
04781 {
04782 if (guardSet_isProbableNull (tab->guards, s))
04783 {
04784 return TRUE;
04785 }
04786
04787 while (tab->kind == US_CBRANCH)
04788 {
04789 tab = tab->env;
04790 }
04791
04792 llassert (usymtab_isDefined (tab));
04793
04794 if (tab->kind == US_FBRANCH)
04795 {
04796 tab = tab->env;
04797 llassert (tab->kind == US_TBRANCH);
04798 }
04799
04800 tab = tab->env;
04801 }
04802
04803 return FALSE;
04804 }
04805
04806 void
04807 usymtab_printGuards ()
04808
04809 {
04810 usymtab ttab = utab;
04811
04812 while (ttab != globtab)
04813 {
04814 llmsg (message ("Guards [%d]: %q", ttab->lexlevel,
04815 guardSet_unparse (ttab->guards)));
04816 ttab = ttab->env;
04817 }
04818 }
04819
04820 void
04821 usymtab_displayAllUses ()
04822
04823 {
04824 usymtab copy;
04825
04826
04827 llassert (utab == globtab);
04828
04829
04830 copy = usymtab_shallowCopy (globtab);
04831
04832 qsort (copy->entries, (size_t)copy->nentries,
04833 sizeof (*copy->entries), (int (*)(const void *, const void *)) uentry_xcompareuses);
04834
04835 usymtab_entries (copy, ue)
04836 {
04837 if (uentry_isValid (ue))
04838 {
04839 filelocList uses = uentry_getUses (ue);
04840 int size = filelocList_realSize (uses);
04841
04842 if (fileloc_isDefined (uentry_whereDefined (ue))
04843 && !fileloc_isLib (uentry_whereDefined (ue))
04844 && (size > 0))
04845 {
04846 llmsg (message ("%q (%q), %d use%p:\n %q",
04847 uentry_getName (ue),
04848 fileloc_unparse (uentry_whereDefined (ue)),
04849 size, filelocList_unparseUses (uses)));
04850 }
04851 }
04852 } end_usymtab_entries;
04853
04854 usymtab_shallowFree (copy);
04855 }
04856
04857 static usymtab
04858 usymtab_getFileTab ()
04859
04860 {
04861 llassert (filetab != NULL);
04862
04863 return filetab;
04864 }
04865
04866 cstring
04867 usymtab_unparseStack ()
04868
04869 {
04870 return (usymtab_unparseStackTab (utab));
04871 }
04872
04873 static cstring
04874 usymtab_unparseStackTab (usymtab t)
04875 {
04876 bool firstOne = TRUE;
04877 cstring ret = cstring_makeLiteral ("[");
04878
04879 while (t != GLOBAL_ENV)
04880 {
04881 if (firstOne)
04882 {
04883 ret = message ("%q %q", ret, usymtab_typeName (t));
04884 firstOne = FALSE;
04885 }
04886 else
04887 {
04888 ret = message ("%q, %q", ret, usymtab_typeName (t));
04889 }
04890 t = t->env;
04891 }
04892
04893 ret = message ("%q ]", ret);
04894 return ret;
04895 }
04896
04897 static cstring
04898 usymtab_typeName ( usymtab t)
04899 {
04900 switch (t->kind)
04901 {
04902 case US_GLOBAL: return cstring_makeLiteral ("global");
04903 case US_NORMAL: return cstring_makeLiteral ("normal");
04904 case US_TBRANCH: return cstring_makeLiteral ("true");
04905 case US_FBRANCH: return cstring_makeLiteral ("false");
04906 case US_CBRANCH: return cstring_makeLiteral ("case");
04907 case US_SWITCH: return cstring_makeLiteral ("switch");
04908 }
04909
04910 BADEXIT;
04911 }
04912
04913 void usymtab_addMustAlias (sRef s, sRef al)
04914
04915 {
04916 if (sRef_isMeaningful (s) && sRef_isMeaningful (al)
04917 && !(sRef_isConst (s) || sRef_isConst (al))
04918 && !(sRef_isAddress (al) && sRef_isDirectParam (sRef_getBase (al)))
04919 && !(sRef_similar (s, al)))
04920 {
04921 utab->aliases = aliasTable_addMustAlias (utab->aliases, s, al);
04922 DPRINTF (("Must alias: %s", aliasTable_unparse (utab->aliases)));
04923
04924
04925
04926
04927
04928 if (sRef_isLocalVar (s) && sRef_isLocalVar (al))
04929 {
04930 utab->aliases = aliasTable_addMustAlias (utab->aliases, al, s);
04931 }
04932 }
04933 else
04934 {
04935 ;
04936 }
04937 }
04938
04939
04940
04941
04942
04943 void usymtab_addForceMustAlias (sRef s, sRef al)
04944
04945 {
04946 if (sRef_isMeaningful (s)
04947 && sRef_isMeaningful (al)
04948 && !(sRef_isConst (s) || sRef_isConst (al))
04949 && !(sRef_isAddress (al) && sRef_isDirectParam (sRef_getBase (al))))
04950 {
04951 utab->aliases = aliasTable_addMustAlias (utab->aliases, s, al);
04952 DPRINTF (("Must alias: %s", aliasTable_unparse (utab->aliases)));
04953
04954
04955
04956
04957
04958 if (sRef_isLocalVar (s) && sRef_isLocalVar (al))
04959 {
04960 utab->aliases = aliasTable_addMustAlias (utab->aliases, al, s);
04961 }
04962 }
04963 else
04964 {
04965 ;
04966 }
04967 }
04968
04969 void usymtab_clearAlias (sRef s)
04970
04971 {
04972
04973 aliasTable_clearAliases (utab->aliases, s);
04974 }
04975
04976 sRefSet usymtab_allAliases (sRef s)
04977
04978 {
04979 if (sRef_isMeaningful (s))
04980 {
04981 sRefSet ret;
04982
04983
04984 ret = sRefSet_unionFree (aliasTable_aliasedBy (utab->aliases, s),
04985 aliasTable_canAlias (utab->aliases, s));
04986 return (ret);
04987 }
04988 else
04989 {
04990 return sRefSet_undefined;
04991 }
04992 }
04993
04994 sRefSet usymtab_canAlias (sRef s)
04995
04996 {
04997 if (sRef_isMeaningful (s))
04998 {
04999 sRefSet res = aliasTable_canAlias (utab->aliases, s);
05000
05001 return res;
05002 }
05003
05004 return sRefSet_undefined;
05005 }
05006
05007 sRefSet usymtab_aliasedBy (sRef s)
05008
05009 {
05010 return (aliasTable_aliasedBy (utab->aliases, s));
05011 }
05012
05013 cstring usymtab_unparseAliases ()
05014
05015 {
05016 return (aliasTable_unparse (utab->aliases));
05017 }
05018
05019
05020
05021
05022
05023
05024
05025
05026 void
05027 usymtab_printOut (void)
05028
05029 {
05030 int i;
05031 usymtab s = utab;
05032 int depth = 0;
05033 char *ind = mstring_copy (" ");
05034
05035 fprintf (g_msgstream, "<<< [symbol table] >>>\n");
05036
05037 while (s != GLOBAL_ENV && s->env != GLOBAL_ENV)
05038 {
05039 cstring tname = usymtab_typeName (s);
05040
05041 if (depth < 5)
05042 {
05043 ind[depth * 3 + 1] = '\0';
05044 }
05045
05046 fprintf (g_msgstream, "level: %d (%s)\n", s->lexlevel,
05047 cstring_toCharsSafe (tname));
05048
05049 cstring_free (tname);
05050
05051 for (i = 0; i < s->nentries; i++)
05052 {
05053 cstring us = uentry_unparseFull (s->entries[i]);
05054 fprintf (g_msgstream, "%s\n", cstring_toCharsSafe (us));
05055 cstring_free (us);
05056 }
05057
05058 if (s->reftable != NULL && s->nentries > 0)
05059 {
05060 fprintf (g_msgstream, "\t<< Ref table >>\n");
05061
05062 for (i = 0; i < s->nentries; i++)
05063 {
05064 fprintf (g_msgstream, "\t%s %3d: %d, %d\n", ind, i,
05065 s->reftable[i]->level,
05066 s->reftable[i]->index);
05067 }
05068 }
05069
05070 ind[depth * 3 + 1] = ' ';
05071 depth++;
05072 s = s->env;
05073 }
05074 fprintf (g_msgstream, "<<< end usymtab >>>\n");
05075 mstring_free (ind);
05076 return;
05077 }
05078
05079 void
05080 usymtab_printTypes ()
05081
05082 {
05083 usymtab_printAllAux (globtab);
05084 }
05085
05086 void
05087 usymtab_printAll (void)
05088
05089 {
05090 usymtab_printAllAux (utab);
05091 }
05092
05093 static void
05094 usymtab_printAllAux (usymtab s)
05095
05096 {
05097 int i;
05098 int depth = 0;
05099 char *ind = mstring_copy (" ");
05100
05101 printf ("[[[ usymtab ]]]");
05102
05103 while (s != GLOBAL_ENV)
05104 {
05105 if (depth < 5)
05106 ind[depth * 3 + 1] = '\0';
05107
05108 if (s->env == GLOBAL_ENV)
05109 {
05110 int looplow;
05111
05112 printf ("level: %d / break: %s / exit: %s\n", s->lexlevel,
05113 cstring_toCharsSafe (bool_unparse (s->mustBreak)),
05114 cstring_toCharsSafe (exitkind_unparse (s->exitCode)));
05115
05116 looplow = 0;
05117
05118 for (i = looplow; i < s->nentries; i++)
05119 {
05120 printf ("%s%3d. %s\n", ind, i,
05121 cstring_toCharsSafe (uentry_unparseFull (s->entries[i])));
05122 }
05123 }
05124 else
05125 {
05126 printf ("level: %d / break: %s / exit: %s\n", s->lexlevel,
05127 cstring_toCharsSafe (bool_unparse (s->mustBreak)),
05128 cstring_toCharsSafe (exitkind_unparse (s->exitCode)));
05129
05130 for (i = 0; i < s->nentries; i++)
05131 {
05132 printf ("%s%3d %s\n", ind, i,
05133 cstring_toCharsSafe (uentry_unparseFull (s->entries[i])));
05134 }
05135 }
05136
05137 ind[depth * 3 + 1] = ' ';
05138 depth++;
05139 s = s->env;
05140 }
05141 printf ("----------\n");
05142 }
05143
05144 void
05145 usymtab_printComplete ()
05146
05147 {
05148 int i;
05149 int depth = 0;
05150 char *ind = mstring_copy (" ");
05151 usymtab s = utab;
05152
05153 while (s != GLOBAL_ENV)
05154 {
05155 if (depth < 5)
05156 {
05157 ind[depth * 3 + 1] = '\0';
05158 }
05159
05160 if (s->env == GLOBAL_ENV)
05161 {
05162 int looplow;
05163
05164 printf ("level: %d\n", s->lexlevel);
05165
05166 looplow = 0;
05167
05168 for (i = looplow; i < s->nentries; i++)
05169 {
05170 printf ("%s%3d %s\n", ind, i,
05171 cstring_toCharsSafe (uentry_unparse (s->entries[i])));
05172 }
05173 }
05174 else
05175 {
05176 printf ("level: %d\n", s->lexlevel);
05177 for (i = 0; i < s->nentries; i++)
05178 {
05179 printf ("%s%3d %s\n", ind, i,
05180 cstring_toCharsSafe (uentry_unparse (s->entries[i])));
05181 }
05182 }
05183
05184 ind[depth * 3 + 1] = ' ';
05185 depth++;
05186 s = s->env;
05187 }
05188
05189 printf ("----------\n");
05190 mstring_free (ind);
05191 }
05192
05193 static cstring
05194 usymtab_unparseLocalAux ( usymtab s)
05195 {
05196 cstring c = message ("lexlevel: %d\n", s->lexlevel);
05197 int i;
05198
05199 for (i = 0; i < s->nentries; i++)
05200 {
05201 c = message ("%q\n%q", c, uentry_unparseFull (s->entries[i]));
05202 }
05203
05204 c = message ("%q\n=========", c);
05205 return (c);
05206 }
05207
05208 static cstring
05209 usymtab_unparseLocalList ( usymtab s)
05210 {
05211 cstring c = message ("[%d/%s/%s] ", s->lexlevel,
05212 bool_unparse (s->mustBreak),
05213 exitkind_unparse (s->exitCode));
05214 int i;
05215
05216 for (i = 0; i < s->nentries; i++)
05217 {
05218 sRef sr = uentry_getSref (s->entries[i]);
05219
05220 if (i == 0)
05221 {
05222 c = message ("%q: %q [%b]", c, uentry_getName (s->entries[i]),
05223 sRef_isStateDefined (sr));
05224 }
05225 else
05226 {
05227 c = message ("%q, %q [%b]", c, uentry_getName (s->entries[i]),
05228 sRef_isStateDefined (sr));
05229 }
05230
05231 }
05232
05233 return (c);
05234 }
05235
05236 void
05237 usymtab_printLocal (void)
05238
05239 {
05240 int i;
05241 usymtab s = utab;
05242
05243 printf ("lexlevel: %d\n", s->lexlevel);
05244
05245 for (i = 0; i < s->nentries; i++)
05246 {
05247 printf ("%s\n", cstring_toCharsSafe (uentry_unparseFull (s->entries[i])));
05248 }
05249
05250 while (s->lexlevel > 1)
05251 {
05252 s = s->env;
05253 }
05254
05255 llassert (usymtab_isDefined (s));
05256
05257 printf ("Params:\n");
05258
05259 for (i = 0; i < s->nentries; i++)
05260 {
05261 printf ("%d: %s\n", i,
05262 cstring_toCharsSafe (uentry_unparseFull (s->entries[i])));
05263 }
05264 }
05265
05266
05267 static bool checkDistinctExternalName (uentry e)
05268
05269
05270 {
05271 int checklen = context_getValue (FLG_EXTERNALNAMELEN);
05272 bool ignorecase = context_getFlag (FLG_EXTERNALNAMECASEINSENSITIVE);
05273 bool gotone = FALSE;
05274 bool extras = FALSE;
05275 bool hasError = FALSE;
05276 cstring name = uentry_rawName (e);
05277 usymtab st = globtab;
05278
05279 if (checklen == 0)
05280 {
05281 ;
05282 }
05283 else
05284 {
05285 if (uentry_isAnyTag (e))
05286 {
05287 checklen++;
05288 }
05289 }
05290
05291 usymtab_entries (st, oe)
05292 {
05293 if (uentry_sameObject (oe, e))
05294 {
05295 continue;
05296 }
05297
05298 if (checklen == 0)
05299 {
05300 if (cstring_equalCaseInsensitive (uentry_rawName (oe), name))
05301 {
05302 if (gotone)
05303 {
05304 extras = TRUE;
05305 break;
05306 }
05307
05308 if (optgenerror
05309 (FLG_DISTINCTEXTERNALNAMES,
05310 message
05311 ("External identifier %q is not distinguishable from %q "
05312 "because alphabetical case is ignored",
05313 uentry_getName (e),
05314 uentry_getName (oe)),
05315 uentry_whereLast (e)))
05316 {
05317 uentry_showWhereAny (oe);
05318 uentry_setHasNameError (oe);
05319 gotone = TRUE;
05320 }
05321 }
05322 }
05323 else
05324 {
05325 if (ignorecase)
05326 {
05327 if (cstring_equalLenCaseInsensitive (uentry_rawName (oe),
05328 name, checklen))
05329 {
05330 if (gotone)
05331 {
05332 extras = TRUE;
05333 break;
05334 }
05335
05336 if (cstring_equalLen (uentry_rawName (oe), name, checklen))
05337 {
05338 if (optgenerror
05339 (FLG_DISTINCTEXTERNALNAMES,
05340
05341 message
05342 ("External identifier %q is not distinguishable from %q "
05343 "in the first %d characters (%q)",
05344 uentry_getName (e),
05345 uentry_getName (oe),
05346 checklen,
05347 cstring_clip (uentry_getName (e), checklen)),
05348
05349 uentry_whereLast (e)))
05350 {
05351 uentry_showWhereAny (oe);
05352 uentry_setHasNameError (oe);
05353 gotone = TRUE;
05354 }
05355 }
05356 else
05357 {
05358 if (gotone)
05359 {
05360 extras = TRUE;
05361 break;
05362 }
05363
05364 if (optgenerror
05365 (FLG_DISTINCTEXTERNALNAMES,
05366 message
05367 ("External identifier %q is not distinguishable from %q "
05368 "in the first %d characters because alphabetical case "
05369 "is ignored",
05370 uentry_getName (e),
05371 uentry_getName (oe),
05372 checklen),
05373 uentry_whereLast (e)))
05374 {
05375 uentry_showWhereAny (oe);
05376 uentry_setHasNameError (oe);
05377 gotone = TRUE;
05378 }
05379 }
05380 }
05381 }
05382 else if (cstring_equalLen (uentry_rawName (oe), name, checklen))
05383 {
05384 if (gotone)
05385 {
05386 extras = TRUE;
05387 break;
05388 }
05389
05390 if (optgenerror
05391 (FLG_DISTINCTEXTERNALNAMES,
05392
05393 message
05394 ("External identifier %q is not distinguishable from %q "
05395 "in the first %d characters (%q)",
05396 uentry_getName (e),
05397 uentry_getName (oe),
05398 checklen,
05399 cstring_clip (uentry_getName (e), checklen)),
05400
05401 uentry_whereLast (e)))
05402 {
05403 uentry_showWhereAny (oe);
05404 uentry_setHasNameError (oe);
05405 gotone = TRUE;
05406 }
05407 }
05408 else
05409 {
05410 ;
05411 }
05412 }
05413 } end_usymtab_entries ;
05414
05415 hasError = gotone;
05416
05417 if (extras)
05418 {
05419 llgenindentmsgnoloc
05420 (cstring_makeLiteral ("One or more additional "
05421 "indistinguishable external "
05422 "names not reported"));
05423 }
05424
05425 return hasError;
05426 }
05427
05428 static bool checkDistinctInternalName (uentry e)
05429
05430
05431 {
05432 usymtab ttab = utab;
05433 cstring name = uentry_rawName (e);
05434 int numchars = context_getValue (FLG_INTERNALNAMELEN);
05435 bool caseinsensitive = context_getFlag (FLG_INTERNALNAMECASEINSENSITIVE);
05436 bool lookalike = context_getFlag (FLG_INTERNALNAMELOOKALIKE);
05437
05438 if (uentry_isAnyTag (e) && (numchars != 0))
05439 {
05440 numchars++;
05441 }
05442
05443 while (usymtab_isDefined (ttab))
05444 {
05445 usymtab_entries (ttab, oe)
05446 {
05447 if (uentry_sameObject (oe, e))
05448 {
05449 continue;
05450 }
05451
05452 switch (cstring_genericEqual
05453 (name, uentry_rawName (oe),
05454 numchars, caseinsensitive, lookalike))
05455 {
05456 case CGE_DISTINCT:
05457
05458 break;
05459 case CGE_SAME:
05460 if (cstring_equal (name, uentry_rawName (oe)))
05461 {
05462 ;
05463 }
05464 else
05465 {
05466 if (optgenerror
05467 (FLG_DISTINCTINTERNALNAMES,
05468
05469 message
05470 ("Internal identifier %q is not distinguishable from %q "
05471 "in the first %d characters (%q)",
05472 uentry_getName (e),
05473 uentry_getName (oe),
05474 numchars,
05475 cstring_clip (uentry_getName (e), numchars)),
05476
05477 uentry_whereLast (e)))
05478 {
05479 uentry_showWhereAny (oe);
05480 uentry_setHasNameError (oe);
05481 return TRUE;
05482 }
05483 }
05484
05485 break;
05486 case CGE_CASE:
05487 if (numchars == 0
05488 || (cstring_length (name) <= numchars))
05489 {
05490 if (optgenerror
05491 (FLG_DISTINCTINTERNALNAMES,
05492 message
05493 ("Internal identifier %q is not distinguishable from %q "
05494 "without case sensitivity",
05495 uentry_getName (e),
05496 uentry_getName (oe)),
05497 uentry_whereLast (e)))
05498 {
05499 uentry_showWhereAny (oe);
05500 uentry_setHasNameError (oe);
05501 return TRUE;
05502 }
05503 }
05504 else
05505 {
05506 if (optgenerror
05507 (FLG_DISTINCTINTERNALNAMES,
05508 message
05509 ("Internal identifier %q is not distinguishable from %q "
05510 "in the first %d characters without case sensitivity",
05511 uentry_getName (e),
05512 uentry_getName (oe),
05513 numchars),
05514 uentry_whereLast (e)))
05515 {
05516 uentry_showWhereAny (oe);
05517 uentry_setHasNameError (oe);
05518 return TRUE;
05519 }
05520 }
05521
05522 break;
05523 case CGE_LOOKALIKE:
05524 if (numchars == 0
05525 || (cstring_length (name) <= numchars))
05526 {
05527 if (optgenerror
05528 (FLG_DISTINCTINTERNALNAMES,
05529 message
05530 ("Internal identifier %q is not distinguishable from %q "
05531 "except by lookalike characters",
05532 uentry_getName (e),
05533 uentry_getName (oe)),
05534 uentry_whereLast (e)))
05535 {
05536 uentry_showWhereAny (oe);
05537 uentry_setHasNameError (oe);
05538 return TRUE;
05539 }
05540 }
05541 else
05542 {
05543 if (optgenerror
05544 (FLG_DISTINCTINTERNALNAMES,
05545 message
05546 ("Internal identifier %q is not distinguishable from %q "
05547 "in the first %d characters except by lookalike characters",
05548 uentry_getName (e),
05549 uentry_getName (oe),
05550 numchars),
05551 uentry_whereLast (e)))
05552 {
05553 uentry_showWhereAny (oe);
05554 uentry_setHasNameError (oe);
05555 return TRUE;
05556 }
05557 }
05558 }
05559 } end_usymtab_entries ;
05560
05561 ttab = ttab->env;
05562 }
05563
05564 return FALSE;
05565 }
05566
05567 void usymtab_checkDistinctName (uentry e, int scope)
05568
05569 {
05570 bool hasError = FALSE;
05571 fileloc where = uentry_whereLast (e);
05572
05573 if (!fileloc_isPreproc (where) && !fileloc_isBuiltin (where))
05574 {
05575 if (scope == globScope)
05576 {
05577 if (context_getFlag (FLG_DISTINCTEXTERNALNAMES))
05578 {
05579 hasError = checkDistinctExternalName (e);
05580 }
05581 }
05582
05583 if (!hasError && context_getFlag (FLG_DISTINCTINTERNALNAMES))
05584 {
05585 hasError = checkDistinctInternalName (e);
05586 }
05587 }
05588
05589 if (hasError)
05590 {
05591 uentry_setHasNameError (e);
05592 }
05593 }
05594