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 # include "lclintMacros.nf"
00029 # include "basic.h"
00030 # include "structNames.h"
00031 # include "nameChecks.h"
00032
00033 static uentry posRedeclared = uentry_undefined;
00034 static fileloc posLoc = fileloc_undefined;
00035 static int nuentries = 0;
00036 static int totuentries = 0;
00037
00038 static void checkGlobalsModifies ( uentry p_ue, sRefSet p_sr) ;
00039 static void uentry_setDeclDef (uentry p_e, fileloc p_f) ;
00040 static bool uentry_isRefCounted (uentry p_ue) ;
00041 static bool uentry_isRefsField (uentry p_ue) ;
00042 static bool uentry_isReallySpecified (uentry p_e) ;
00043 static void uentry_checkIterArgs (uentry p_ue);
00044 static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
00045
00046
00047 static void checkAliasState ( uentry p_old,
00048 uentry p_unew,
00049 bool p_mustConform, bool p_completeConform)
00050 ;
00051 static void checkNullState ( uentry p_old,
00052 uentry p_unew,
00053 bool p_mustConform, bool p_completeConform)
00054 ;
00055
00056 static void checkVarConformance ( uentry p_old,
00057 uentry p_unew,
00058 bool p_mustConform, bool p_completeConform)
00059 ;
00060
00061 # ifndef NOLCL
00062 static void uentry_setHasMods (uentry p_ue) ;
00063 static void uentry_setHasGlobs (uentry p_ue) ;
00064 # endif
00065
00066 static void uentry_reallyFree ( uentry p_e);
00067
00068 static void uentry_setSpecDef ( uentry p_e, fileloc p_f)
00069
00070 ;
00071
00072 static void returnValueError ( uentry p_old, uentry p_unew);
00073 static void nargsError ( uentry p_old, uentry p_unew);
00074 static cstring paramStorageName (uentry p_ue) ;
00075 static cstring fcnErrName (uentry p_ue) ;
00076 static cstring checkedName (chkind p_checked) ;
00077 static void
00078 paramTypeError ( uentry p_old, uentry p_oldCurrent,
00079 ctype p_oldType, uentry p_unew,
00080 uentry p_newCurrent,
00081 ctype p_newType, int p_paramno) ;
00082
00083 static uentry
00084 uentry_makeVariableAux (cstring p_n, ctype p_t, fileloc p_f,
00085 sRef p_s, bool p_priv, vkind p_kind);
00086
00087 static uentry uentry_alloc (void)
00088 {
00089 uentry ue = (uentry) dmalloc (sizeof (*ue));
00090 nuentries++;
00091 totuentries++;
00092
00093 return ue;
00094 }
00095
00096 static cstring uentry_getOptName (uentry p_e) ;
00097 static void uentry_copyInto ( uentry p_unew, uentry p_old);
00098 static void uentry_setNullState ( uentry p_ue, nstate p_ns);
00099 static void uentry_setAliasKind ( uentry p_ue, alkind p_ak);
00100 static uinfo uinfo_copy (uinfo p_u, ekind p_kind);
00101 static void uinfo_free ( uinfo p_u, ekind p_kind);
00102 static void uvinfo_free ( uvinfo p_u);
00103
00104 # ifdef DOANNOTS
00105
00106 static cstring ancontext_unparse (ancontext an)
00107 {
00108 switch (an)
00109 {
00110 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
00111 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
00112 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
00113 case AN_SUFIELD: return cstring_makeLiteral ("su field");
00114 case AN_TDEFN: return cstring_makeLiteral ("type definition");
00115 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
00116 case AN_CONST: return cstring_makeLiteral ("constant");
00117 BADDEFAULT;
00118 }
00119 BADEXIT;
00120 }
00121
00122 static int annots[AN_LAST][QU_LAST];
00123 static int decls[AN_LAST];
00124 static int shdecls[AN_LAST];
00125 static int idecls[AN_LAST];
00126
00127 void initAnnots ()
00128 {
00129 int i, j;
00130
00131 for (i = AN_UNKNOWN; i < AN_LAST; i++)
00132 {
00133 decls[i] = 0;
00134 shdecls[i] = 0;
00135 idecls[i] = 0;
00136
00137 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00138 {
00139 annots[i][j] = 0;
00140 }
00141 }
00142 }
00143
00144 static void tallyAnnot (ancontext ac, qual q)
00145 {
00146 (annots[ac][q])++;
00147 }
00148
00149 void printAnnots ()
00150 {
00151 int total[QU_LAST];
00152 int alltotals = 0;
00153 int totdecls = 0;
00154 int totshdecls = 0;
00155 int totidecls = 0;
00156 int i, j;
00157
00158 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00159 {
00160 total[j] = 0;
00161 }
00162
00163 for (i = AN_UNKNOWN; i < AN_LAST; i++)
00164 {
00165 int tmptot;
00166
00167 if (decls[i] > 0)
00168 {
00169 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
00170 ancontext_unparse (i),
00171 decls[i], shdecls[i], idecls[i]);
00172
00173 totdecls += decls[i];
00174 totshdecls += shdecls[i];
00175 totidecls += idecls[i];
00176
00177 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00178 {
00179 total[j] += annots[i][j];
00180 alltotals += annots[i][j];
00181 }
00182
00183 printf (" Allocation:\n");
00184
00185 tmptot = 0;
00186
00187 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00188 {
00189 if (qual_isAliasQual (j) && !qual_isUnique (j))
00190 {
00191 if (annots[i][j] > 0)
00192 {
00193 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
00194 100.0 * (double)annots[i][j] / (double)decls[i]);
00195 tmptot += annots[i][j];
00196 }
00197 }
00198 }
00199
00200 printf (" Exposure:\n");
00201
00202 tmptot = 0;
00203
00204 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00205 {
00206 if (qual_isExQual (j))
00207 {
00208 if (annots[i][j] > 0)
00209 {
00210 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
00211 100.0 * (double)annots[i][j] / (double)decls[i]);
00212 tmptot += annots[i][j];
00213 }
00214 }
00215 }
00216
00217 printf (" Definition:\n");
00218
00219 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00220 {
00221 if (qual_isAllocQual (j))
00222 {
00223 if (annots[i][j] > 0)
00224 {
00225 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
00226 100.0 * (double)annots[i][j] / (double)decls[i]);
00227 }
00228 }
00229 }
00230
00231 printf (" Null:\n");
00232
00233 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00234 {
00235 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
00236 {
00237 if (annots[i][j] > 0)
00238 {
00239 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
00240 100.0 * (double)annots[i][j] / (double)decls[i]);
00241 }
00242 }
00243 }
00244
00245 printf ("\n");
00246 }
00247 }
00248
00249 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00250 {
00251 bool hasone = FALSE;
00252
00253 for (i = AN_UNKNOWN; i < AN_LAST; i++)
00254 {
00255 if (annots[i][j] > 0)
00256 {
00257 hasone = TRUE;
00258 break;
00259 }
00260 }
00261
00262 if (hasone)
00263 {
00264 printf ("Annotation: %s\n", qual_unparse (j));
00265
00266 for (i = AN_UNKNOWN; i < AN_LAST; i++)
00267 {
00268 if (annots[i][j] > 0)
00269 {
00270 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
00271 }
00272 }
00273 printf ("\n");
00274 }
00275 }
00276
00277 printf ("All Contexts\n");
00278
00279 for (j = QU_UNKNOWN; j < QU_LAST; j++)
00280 {
00281 if (total[j] > 0)
00282 {
00283 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
00284 100.0 * (double)total[j] / (double)(totdecls));
00285 }
00286 }
00287 printf ("\n");
00288
00289 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
00290
00291 extern void uentry_tallyAnnots (uentry u, ancontext kind)
00292 {
00293 alkind ak = sRef_getAliasKind (u->sref);
00294 exkind ek = sRef_getExKind (u->sref);
00295 nstate ns = sRef_getNullState (u->sref);
00296 sstate ss = sRef_getDefState (u->sref);
00297 bool recordUnknown = FALSE;
00298
00299
00300 if (kind == AN_UNKNOWN)
00301 {
00302 ekind e = u->ukind;
00303
00304 if (e == KENDITER)
00305 {
00306 return;
00307 }
00308 else if (e == KCONST || e == KENUMCONST)
00309 {
00310 kind = AN_CONST;
00311 }
00312 else if (e == KFCN || e == KITER)
00313 {
00314 uentryList params = uentry_getParams (u);
00315 bool hasRet = FALSE;
00316
00317 uentryList_elements (params, current)
00318 {
00319 if (uentry_isReturned (current))
00320 {
00321 hasRet = TRUE;
00322 }
00323 if (!uentry_isElipsisMarker (current))
00324 {
00325 uentry_tallyAnnots (current, AN_FCNPARAM);
00326 }
00327 } end_uentryList_elements;
00328
00329 kind = AN_FCNRETURN;
00330
00331 if (ctype_isFunction (u->utype)
00332 && !hasRet
00333 && ctype_isVisiblySharable (ctype_realType (ctype_returnValue (u->utype))))
00334 {
00335 recordUnknown = TRUE;
00336 }
00337 }
00338 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
00339 {
00340 ctype t = ctype_realType (u->utype);
00341
00342 if (ctype_isSU (t))
00343 {
00344 uentryList fields = ctype_getFields (t);
00345
00346 uentryList_elements (fields, current)
00347 {
00348 uentry_tallyAnnots (current, AN_SUFIELD);
00349 }
00350 } end_uentryList_elements;
00351
00352 kind = AN_TDEFN;
00353
00354 if (ctype_isVisiblySharable (u->utype))
00355 {
00356 recordUnknown = TRUE;
00357 }
00358 }
00359 else
00360 {
00361 kind = AN_GSVAR;
00362
00363
00364 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
00365 {
00366 recordUnknown = TRUE;
00367 }
00368 }
00369 }
00370
00371 decls[kind]++;
00372
00373 if (kind == AN_FCNRETURN)
00374 {
00375 if (recordUnknown)
00376 {
00377 shdecls[kind]++;
00378 idecls[kind]++;
00379 }
00380 else
00381 {
00382 ;
00383 }
00384 }
00385 else
00386 {
00387 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
00388 {
00389 shdecls[kind]++;
00390 }
00391
00392 if (ctype_isRealPointer (ctype_realType (u->utype)))
00393 {
00394 idecls[kind]++;
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 switch (ss)
00408 {
00409 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
00410 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
00411 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
00412 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
00413 default: break;
00414 }
00415
00416 if (uentry_isReturned (u))
00417 {
00418 tallyAnnot (kind, QU_RETURNED);
00419 }
00420
00421 switch (ak)
00422 {
00423 case AK_UNKNOWN:
00424 if (ctype_isRefCounted (ctype_realType (u->utype))
00425 || (ctype_isFunction (u->utype) &&
00426 ctype_isRefCounted (ctype_realType (ctype_returnValue (u->utype)))))
00427 {
00428 ;
00429 }
00430 else
00431 {
00432 if (kind == AN_FCNPARAM)
00433 {
00434 tallyAnnot (kind, QU_TEMP);
00435 }
00436 else if (recordUnknown)
00437 {
00438 if (kind == AN_FCNRETURN)
00439 {
00440 }
00441 tallyAnnot (kind, QU_UNKNOWN);
00442 }
00443 }
00444 break;
00445 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
00446 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
00447 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
00448 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
00449 case AK_IMPTEMP:
00450 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
00451 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
00452 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
00453 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
00454 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
00455 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
00456 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
00457 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
00458 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
00459 case AK_IMPDEPENDENT:
00460 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
00461 case AK_ERROR:
00462 case AK_FRESH:
00463 case AK_STACK:
00464 case AK_LOCAL:
00465 break;
00466 }
00467
00468 switch (ek)
00469 {
00470 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
00471 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
00472 default: break;
00473 }
00474
00475 switch (ns)
00476 {
00477 case NS_ERROR: break;
00478 case NS_UNKNOWN: break;
00479 case NS_NOTNULL: break;
00480 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
00481 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
00482 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
00483 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
00484 case NS_DEFNULL:
00485 case NS_ABSNULL: break;
00486 }
00487 }
00488
00489 # endif
00490
00491 static cstring specCode_unparse (specCode s)
00492 {
00493 switch (s)
00494 {
00495 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
00496 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
00497 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
00498 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
00499 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
00500 }
00501
00502 BADEXIT;
00503 }
00504
00505 static specCode specCode_fromInt (int i)
00506 {
00507
00508 llassert (i >= SPC_NONE && i < SPC_LAST);
00509
00510 return ((specCode) i);
00511
00512 }
00513
00514 cstring uentry_specOrDefName (uentry u)
00515 {
00516 if (uentry_isDeclared (u))
00517 {
00518 return cstring_makeLiteralTemp ("previously declared");
00519 }
00520 else
00521 {
00522 return cstring_makeLiteralTemp ("specified");
00523 }
00524 }
00525
00526 cstring uentry_specDeclName (uentry u)
00527 {
00528 if (uentry_isDeclared (u))
00529 {
00530 return cstring_makeLiteralTemp ("previous declaration");
00531 }
00532 else
00533 {
00534 return cstring_makeLiteralTemp ("specification");
00535 }
00536 }
00537
00538 static cstring uentry_reDefDecl (uentry old, uentry unew)
00539 {
00540 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
00541 {
00542 return cstring_makeLiteralTemp ("redefined");
00543 }
00544 else if (uentry_isCodeDefined (unew))
00545 {
00546 return cstring_makeLiteralTemp ("defined");
00547 }
00548 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
00549 {
00550 return cstring_makeLiteralTemp ("redeclared");
00551 }
00552 else
00553 {
00554 return cstring_makeLiteralTemp ("declared");
00555 }
00556 }
00557
00558 static fileloc setLocation (void)
00559 {
00560 fileloc fl = context_getSaveLocation ();
00561
00562 if (fileloc_isDefined (fl))
00563 {
00564 return fl;
00565 }
00566 else
00567 {
00568 return fileloc_copy (g_currentloc);
00569 }
00570 }
00571
00572 uentry uentry_makeEnumConstant (cstring n, ctype t)
00573 {
00574 fileloc loc = setLocation ();
00575 uentry ue = uentry_makeConstant (n, t, loc);
00576
00577 ue->ukind = KENUMCONST;
00578 uentry_setDefined (ue, loc);
00579 return ue;
00580 }
00581
00582 uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
00583 {
00584 fileloc loc = setLocation ();
00585 uentry ue = uentry_makeConstant (n, t, loc);
00586 ctype etype = exprNode_getType (expr);
00587
00588 if (!ctype_isRealInt (etype)) {
00589 voptgenerror
00590 (FLG_ENUMMEMBERS,
00591 message
00592 ("Value of enum member is not an integeral type (type %s): %s",
00593 ctype_unparse (etype), exprNode_unparse (expr)),
00594 exprNode_loc (expr));
00595 }
00596
00597 ue->ukind = KENUMCONST;
00598 uentry_setDefined (ue, loc);
00599 return ue;
00600 }
00601
00602 # ifndef NOLCL
00603 uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
00604 {
00605 uentry ue = uentry_makeConstant (n, t, loc);
00606
00607 ue->ukind = KENUMCONST;
00608 return ue;
00609 }
00610 # endif
00611
00612 uentry uentry_makeVariableLoc (cstring n, ctype t)
00613 {
00614 return uentry_makeVariable (n, t, setLocation (), FALSE);
00615 }
00616
00617 # ifndef NOLCL
00618 uentry uentry_makeUnnamedVariable (ctype t)
00619 {
00620 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
00621 }
00622 # endif
00623
00624 uentry uentry_makeIdDatatype (idDecl id)
00625 {
00626 ctype ct = idDecl_getCtype (id);
00627 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
00628 MAYBE, MAYBE, setLocation ());
00629
00630 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
00631
00632 if (!ynm_isOn (ue->info->datatype->abs))
00633 {
00634 if (ctype_isUnknown (ct))
00635 {
00636 ue->info->datatype->mut = MAYBE;
00637 }
00638 else
00639 {
00640 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
00641 }
00642 }
00643
00644 return ue;
00645 }
00646
00647 void uentry_checkParams (uentry ue)
00648 {
00649 if (uentry_isValid (ue))
00650 {
00651 bool isExt = uentry_isExtern (ue);
00652
00653 if (uentry_isRealFunction (ue))
00654 {
00655 uentryList params = uentry_getParams (ue);
00656
00657 uentryList_elements (params, current)
00658 {
00659 if (uentry_isValid (current))
00660 {
00661 ctype ct = current->utype;
00662
00663 if (ctype_isFixedArray (ct))
00664 {
00665 if (ctype_isArray (ctype_baseArrayPtr (ct))
00666 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
00667 {
00668 ;
00669 }
00670 else
00671 {
00672 voptgenerror
00673 (FLG_FIXEDFORMALARRAY,
00674 message ("Function parameter %q declared as "
00675 "manifest array (size constant is meaningless)",
00676 uentry_getName (current)),
00677 uentry_whereDeclared (current));
00678 }
00679 }
00680 else
00681 {
00682 if (ctype_isArray (ct))
00683 {
00684 voptgenerror
00685 (FLG_FORMALARRAY,
00686 message ("Function parameter %q declared as "
00687 "array (treated as pointer)",
00688 uentry_getName (current)),
00689 uentry_whereDeclared (current));
00690 }
00691 }
00692
00693 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
00694 {
00695 if (ctype_isAbstract (ct) &&
00696 (isExt || (ctype_isAbstract (ctype_realType (ct))
00697 && !context_hasFileAccess (ctype_typeId (ct)))))
00698 {
00699 vgenhinterror
00700 (FLG_INCONDEFS,
00701 message
00702 ("Function %q declared with notnull parameter %q of abstract "
00703 "type %s",
00704 uentry_getName (ue),
00705 uentry_getName (current),
00706 ctype_unparse (ct)),
00707 message
00708 ("Since %s is an abstract type, notnull can only be "
00709 "used for parameters if the function is static to a "
00710 "module where %s is accessible.",
00711 ctype_unparse (ct),
00712 ctype_unparse (ct)),
00713 uentry_whereDeclared (current));
00714 }
00715 }
00716 }
00717 } end_uentryList_elements;
00718
00719 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
00720 {
00721 ctype ct = ue->utype;
00722
00723 if (ctype_isAbstract (ct)
00724 && (isExt || (ctype_isAbstract (ctype_realType (ct))
00725 && !context_hasFileAccess (ctype_typeId (ct)))))
00726 {
00727 vgenhinterror
00728 (FLG_INCONDEFS,
00729 message
00730 ("%s %q declared %s notnull storage of abstract type %s",
00731 ekind_capName (uentry_getKind (ue)),
00732 uentry_getName (ue),
00733 fcnErrName (ue),
00734 ctype_unparse (ct)),
00735 message
00736 ("Since %s is an abstract type, notnull can only be used "
00737 "if it is static to a module where %s is accessible.",
00738 ctype_unparse (ct),
00739 ctype_unparse (ct)),
00740 uentry_whereDeclared (ue));
00741 }
00742 }
00743 }
00744 }
00745 }
00746
00747 static void reflectImplicitFunctionQualifiers ( uentry ue, bool spec)
00748 {
00749 alkind ak = sRef_getAliasKind (ue->sref);
00750
00751 if (alkind_isRefCounted (ak))
00752 {
00753 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
00754 }
00755 else
00756 {
00757 if (alkind_isUnknown (ak))
00758 {
00759 exkind ek = sRef_getExKind (ue->sref);
00760
00761 if (exkind_isKnown (ek))
00762 {
00763 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
00764 }
00765 else
00766 {
00767 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
00768 {
00769 if (ctype_isVisiblySharable
00770 (ctype_realType (ctype_returnValue (ue->utype))))
00771 {
00772 if (uentryList_hasReturned (uentry_getParams (ue)))
00773 {
00774 ;
00775 }
00776 else
00777 {
00778 sRef_setAliasKind (ue->sref, AK_IMPONLY,
00779 fileloc_undefined);
00780 }
00781 }
00782 }
00783 }
00784 }
00785 }
00786 }
00787
00788 static uentry
00789 uentry_makeFunctionAux (cstring n, ctype t,
00790 typeIdSet access,
00791 globSet globs,
00792 sRefSet mods,
00793 fileloc f, bool priv,
00794 bool isForward)
00795 {
00796 uentry e = uentry_alloc ();
00797 ctype ret;
00798
00799 if (ctype_isFunction (t))
00800 {
00801 ret = ctype_returnValue (t);
00802 }
00803 else
00804 {
00805 if (ctype_isKnown (t))
00806 {
00807 llbug (message ("not function: %s", ctype_unparse (t)));
00808 }
00809 ret = ctype_unknown;
00810 }
00811
00812 e->ukind = KFCN;
00813
00814 if (fileloc_isSpec (f) || fileloc_isImport (f))
00815 {
00816 e->whereSpecified = f;
00817 e->whereDeclared = fileloc_undefined;
00818 }
00819 else
00820 {
00821 e->whereSpecified = fileloc_undefined;
00822 e->whereDeclared = f;
00823 }
00824
00825
00826 e->uname = cstring_copy (n);
00827 e->utype = t;
00828 e->storageclass = SCNONE;
00829
00830 e->sref = sRef_makeType (ret);
00831
00832 if (ctype_isUA (ret))
00833 {
00834 sRef_setStateFromType (e->sref, ret);
00835 }
00836
00837 e->used = FALSE;
00838 e->lset = FALSE;
00839 e->uses = filelocList_new ();
00840 e->isPrivate = priv;
00841 e->hasNameError = FALSE;
00842
00843 e->info = (uinfo) dmalloc (sizeof (*e->info));
00844 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
00845
00846 e->info->fcn->hasMods = sRefSet_isDefined (mods);
00847 e->info->fcn->hasGlobs = globSet_isDefined (globs);
00848
00849 e->info->fcn->exitCode = XK_UNKNOWN;
00850 e->info->fcn->nullPred = QU_UNKNOWN;
00851 e->info->fcn->specialCode = SPC_NONE;
00852
00853 e->info->fcn->access = access;
00854 e->info->fcn->globs = globs;
00855 e->info->fcn->defparams = uentryList_undefined;
00856
00857 sRef_setDefined (e->sref, f);
00858 e->whereDefined = fileloc_undefined;
00859
00860 e->info->fcn->mods = sRefSet_undefined;
00861 e->info->fcn->specclauses = NULL;
00862 checkGlobalsModifies (e, mods);
00863 e->info->fcn->mods = mods;
00864
00865 return (e);
00866 }
00867
00868 uentry uentry_makeIdFunction (idDecl id)
00869 {
00870 uentry ue =
00871 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
00872 typeId_invalid, globSet_undefined,
00873 sRefSet_undefined,
00874 setLocation ());
00875
00876 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
00877 reflectImplicitFunctionQualifiers (ue, FALSE);
00878
00879 if (!uentry_isStatic (ue)
00880 && cstring_equalLit (ue->uname, "main"))
00881 {
00882 ctype typ = ue->utype;
00883 ctype retval;
00884 uentryList args;
00885
00886 llassert (ctype_isFunction (typ));
00887
00888 retval = ctype_returnValue (typ);
00889
00890 if (!ctype_isInt (retval))
00891 {
00892 voptgenerror
00893 (FLG_MAINTYPE,
00894 message ("Function main declared to return %s, should return int",
00895 ctype_unparse (retval)),
00896 uentry_whereDeclared (ue));
00897 }
00898
00899 args = ctype_argsFunction (typ);
00900
00901 if (uentryList_isMissingParams (args)
00902 || uentryList_size (args) == 0)
00903 {
00904 ;
00905 }
00906 else
00907 {
00908 if (uentryList_size (args) != 2)
00909 {
00910 voptgenerror
00911 (FLG_MAINTYPE,
00912 message ("Function main declared with %d arg%p, "
00913 "should have 2 (int argc, char *argv[])",
00914 uentryList_size (args)),
00915 uentry_whereLast (ue));
00916 }
00917 else
00918 {
00919 uentry arg = uentryList_getN (args, 0);
00920 ctype ct = uentry_getType (arg);
00921
00922 if (!ctype_isInt (ct))
00923 {
00924 voptgenerror
00925 (FLG_MAINTYPE,
00926 message ("Parameter 1, %q, of function main declared "
00927 "with type %t, should have type int",
00928 uentry_getName (arg), ct),
00929 uentry_whereDeclared (arg));
00930 }
00931
00932 arg = uentryList_getN (args, 1);
00933 ct = uentry_getType (arg);
00934
00935 if (ctype_isArrayPtr (ct)
00936 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
00937 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
00938 {
00939 ;
00940 }
00941 else
00942 {
00943 voptgenerror
00944 (FLG_MAINTYPE,
00945 message ("Parameter 2, %q, of function main declared "
00946 "with type %t, should have type char **",
00947 uentry_getName (arg), ct),
00948 uentry_whereDeclared (arg));
00949 }
00950 }
00951 }
00952 }
00953
00954 return ue;
00955 }
00956
00957 static void uentry_implicitParamAnnots ( uentry e)
00958 {
00959 alkind ak = sRef_getAliasKind (e->sref);
00960
00961 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
00962 && context_getFlag (FLG_PARAMIMPTEMP))
00963 {
00964 exkind ek = sRef_getExKind (e->sref);
00965
00966 if (exkind_isKnown (ek))
00967 {
00968 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
00969 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
00970 }
00971 else
00972 {
00973 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
00974 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
00975 }
00976 }
00977 }
00978
00979 static uentry
00980 uentry_makeVariableParamAux (cstring n, ctype t, sRef s, sstate defstate)
00981 {
00982 cstring pname = makeParam (n);
00983 uentry e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
00984
00985 cstring_free (pname);
00986 uentry_implicitParamAnnots (e);
00987
00988 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
00989 {
00990 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
00991 e->info->var->defstate = defstate;
00992 }
00993
00994 return (e);
00995 }
00996
00997 # ifndef NOLCL
00998 void
00999 uentry_setRefCounted (uentry e)
01000 {
01001 if (uentry_isValid (e))
01002 {
01003 uentry_setAliasKind (e, AK_REFCOUNTED);
01004 sRef_storeState (e->sref);
01005 }
01006 }
01007 # endif
01008
01009 void
01010 uentry_setStatic (uentry c)
01011 {
01012 if (uentry_isValid (c))
01013 {
01014 alkind ak = sRef_getAliasKind (c->sref);
01015 c->storageclass = SCSTATIC;
01016
01017 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
01018 {
01019 if (!alkind_isUnknown (ak)
01020 && !alkind_isStatic (ak))
01021 {
01022 if (!(ctype_isRealPointer (uentry_getType (c)))
01023 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
01024 && !alkind_isRefCounted (ak))
01025 {
01026 if (alkind_isImplicit (ak)
01027 && alkind_isDependent (ak)
01028 && ctype_isArray (uentry_getType (c)))
01029 {
01030 ;
01031 }
01032 else
01033 {
01034 voptgenerror
01035 (FLG_INCONDEFS,
01036 message ("Static storage %q declared as %s",
01037 uentry_getName (c),
01038 alkind_unparse (ak)),
01039 uentry_whereDeclared (c));
01040 }
01041 }
01042 }
01043 else
01044 {
01045 if (alkind_isUnknown (ak)
01046 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
01047 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
01048 {
01049 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
01050 sRef_setOrigAliasKind (c->sref, AK_STATIC);
01051 }
01052 }
01053 }
01054 }
01055 }
01056
01057 void
01058 uentry_setExtern (uentry c)
01059 {
01060 if (uentry_isValid (c))
01061 c->storageclass = SCEXTERN;
01062 }
01063
01064 void
01065 uentry_setParamNo (uentry ue, int pno)
01066 {
01067 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
01068 sRef_setParamNo (ue->sref, pno);
01069 }
01070
01071 static
01072 void checkGlobalsModifies ( uentry ue, sRefSet sr)
01073 {
01074 sRefSet_allElements (sr, el)
01075 {
01076 sRef base = sRef_getRootBase (el);
01077
01078 if (sRef_isGlobal (base) || sRef_isInternalState (base)
01079 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
01080 {
01081 if (!globSet_member (ue->info->fcn->globs, base))
01082 {
01083 if (uentry_hasGlobs (ue)
01084 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
01085 {
01086 if (optgenerror
01087 (FLG_WARNMISSINGGLOBALS,
01088 message
01089 ("Modifies list for %q uses global %q, "
01090 "not included in globals list.",
01091 uentry_getName (ue),
01092 sRef_unparse (base)),
01093 uentry_whereLast (ue)))
01094 {
01095 uentry_showWhereSpecified (ue);
01096 }
01097 }
01098
01099 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
01100 base);
01101 if (sRef_isFileStatic (base))
01102 {
01103 context_recordFileGlobals (ue->info->fcn->globs);
01104 }
01105 }
01106 }
01107 } end_sRefSet_allElements;
01108 }
01109
01110 uentry
01111 uentry_makeVariableSrefParam (cstring n, ctype t, sRef s)
01112 {
01113 return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
01114 }
01115
01116 void
01117 uentry_fixupSref (uentry ue)
01118 {
01119 sRef sr;
01120
01121 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
01122 {
01123 return;
01124 }
01125
01126 sr = uentry_getSref (ue);
01127
01128 sRef_resetState (sr);
01129 sRef_clearDerived (sr);
01130
01131 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
01132 llassert (sRef_isValid (sr));
01133
01134 if (uentry_isVariable (ue))
01135 {
01136 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
01137 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
01138 }
01139 }
01140
01141 void uentry_setSpecialClauses (uentry ue, specialClauses clauses)
01142 {
01143 llassert (uentry_isFunction (ue));
01144 llassert (!specialClauses_isDefined (ue->info->fcn->specclauses));
01145
01146 ue->info->fcn->specclauses = clauses;
01147 specialClauses_checkAll (ue);
01148 }
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164 void
01165 uentry_setModifies (uentry ue, sRefSet sr)
01166 {
01167 if (sRef_modInFunction ())
01168 {
01169 llparseerror
01170 (message ("Modifies list not in function context. "
01171 "A modifies list can only appear following the parameter list "
01172 "in a function declaration or header."));
01173
01174 return;
01175 }
01176
01177 if (sRefSet_hasStatic (sr))
01178 {
01179 context_recordFileModifies (sr);
01180 }
01181
01182 if (uentry_isValid (ue))
01183 {
01184 if (uentry_isIter (ue))
01185 {
01186 llassert (sRefSet_isUndefined (ue->info->iter->mods));
01187 ue->info->iter->mods = sr;
01188 }
01189 else
01190 {
01191 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
01192 {
01193 uentry_makeVarFunction (ue);
01194 }
01195
01196 llassertfatal (uentry_isFunction (ue));
01197 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
01198
01199 ue->info->fcn->mods = sr;
01200 ue->info->fcn->hasMods = TRUE;
01201
01202 checkGlobalsModifies (ue, sr);
01203 }
01204
01205 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
01206 {
01207 ue->info->fcn->hasGlobs = TRUE;
01208 }
01209 }
01210 else
01211 {
01212 sRefSet_free (sr);
01213 }
01214 }
01215
01216
01217
01218
01219
01220 static void
01221 checkGlobalsConformance ( uentry old,
01222 uentry unew,
01223 bool mustConform, bool completeConform)
01224 {
01225 bool hasInternalState = FALSE;
01226
01227 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
01228
01229 if (globSet_isDefined (unew->info->fcn->globs))
01230 {
01231 globSet_allElements (unew->info->fcn->globs, el)
01232 {
01233 if (sRef_isFileStatic (el))
01234 {
01235 sRef sr = globSet_lookup (old->info->fcn->globs, el);
01236
01237 if (sRef_isInvalid (sr))
01238 {
01239 bool hasError = FALSE;
01240
01241 if (!hasInternalState
01242 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
01243 sRef_makeInternalState ()))
01244 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
01245 sRef_makeSpecState ())))
01246 {
01247 if (mustConform
01248 && !uentry_isStatic (old)
01249 && optgenerror
01250 (FLG_INCONDEFS,
01251 message ("Globals list for %q includes internal state, %q, "
01252 "but %s without globals internalState.",
01253 uentry_getName (old),
01254 sRef_unparse (el),
01255 uentry_specOrDefName (old)),
01256 uentry_whereLast (unew)))
01257 {
01258 uentry_showWhereSpecified (old);
01259 hasError = TRUE;
01260 }
01261
01262 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
01263 sRef_makeInternalState ());
01264 hasInternalState = TRUE;
01265 }
01266
01267 if (!hasError
01268 && fileloc_sameFile (uentry_whereDeclared (unew),
01269 uentry_whereDeclared (old)))
01270 {
01271 if (mustConform
01272 && optgenerror
01273 (FLG_INCONDEFS,
01274 message ("Function %q inconsistently %rdeclared (in "
01275 "same file) with file static global %q in "
01276 "globals list",
01277 uentry_getName (unew),
01278 uentry_isDeclared (old),
01279 sRef_unparse (el)),
01280 uentry_whereDeclared (unew)))
01281 {
01282 uentry_showWhereSpecified (old);
01283 }
01284 }
01285 }
01286
01287 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
01288 context_recordFileGlobals (old->info->fcn->globs);
01289 }
01290 else
01291 {
01292 sRef sr = globSet_lookup (old->info->fcn->globs, el);
01293
01294 if (sRef_isInvalid (sr))
01295 {
01296 if (mustConform
01297 && optgenerror
01298 (FLG_INCONDEFS,
01299 message ("Function %q inconsistently %rdeclared with "
01300 "%q in globals list",
01301 uentry_getName (unew),
01302 uentry_isDeclared (old),
01303 sRef_unparse (el)),
01304 uentry_whereDeclared (unew)))
01305 {
01306 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
01307 uentry_showWhereSpecified (old);
01308 }
01309 }
01310 else
01311 {
01312 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
01313 {
01314 if (mustConform
01315 && optgenerror
01316 (FLG_INCONDEFS,
01317 message
01318 ("Function %q global %q inconsistently "
01319 "%rdeclared as %qout global",
01320 uentry_getName (unew),
01321 sRef_unparse (el),
01322 uentry_isDeclared (old),
01323 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
01324 uentry_whereDeclared (unew)))
01325 {
01326 uentry_showWhereSpecified (old);
01327 }
01328 }
01329 }
01330 }
01331 } end_globSet_allElements ;
01332
01333 if (completeConform)
01334 {
01335 globSet_allElements (old->info->fcn->globs, el)
01336 {
01337 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
01338
01339 if (sRef_isInvalid (sr))
01340 {
01341 if (mustConform
01342 && uentry_isReallySpecified (old)
01343 && optgenerror
01344 (FLG_NEEDSPEC,
01345 message ("Function %q specified with %q in globals list, "
01346 "but declared without %q",
01347 uentry_getName (unew),
01348 sRef_unparse (el),
01349 sRef_unparse (el)),
01350 uentry_whereDeclared (unew)))
01351 {
01352 uentry_showWhereSpecified (old);
01353 }
01354 }
01355 } end_globSet_allElements;
01356 }
01357 }
01358 else
01359 {
01360 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
01361 {
01362 if (uentry_isReallySpecified (old)
01363 && optgenerror
01364 (FLG_NEEDSPEC,
01365 message ("%s %q specified with globals list, but "
01366 "declared with no globals",
01367 ekind_capName (unew->ukind),
01368 uentry_getName (unew)),
01369 uentry_whereDeclared (unew)))
01370 {
01371 llgenindentmsg
01372 (message ("Specification globals: %q",
01373 globSet_unparse (old->info->fcn->globs)),
01374 uentry_whereSpecified (old));
01375 }
01376 }
01377
01378 unew->info->fcn->globs = globSet_copy (unew->info->fcn->globs,
01379 old->info->fcn->globs);
01380 }
01381 }
01382
01383
01384
01385
01386
01387
01388
01389 static void
01390 checkModifiesConformance ( uentry old, uentry unew,
01391 bool mustConform, bool completeConform)
01392 {
01393 sRefSet newMods;
01394 bool changedMods = FALSE;
01395 bool modInternal = FALSE;
01396
01397 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
01398
01399 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
01400 newMods = unew->info->fcn->mods;
01401
01402 if (sRefSet_isEmpty (newMods))
01403 {
01404 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
01405 && uentry_isReallySpecified (old))
01406 {
01407 if (optgenerror
01408 (FLG_NEEDSPEC,
01409 message ("%s %q specified with modifies clause, "
01410 "but declared with no modifies clause",
01411 ekind_capName (unew->ukind),
01412 uentry_getName (unew)),
01413 uentry_whereDeclared (unew)))
01414 {
01415 llgenindentmsg (message ("Specification has modifies %q",
01416 sRefSet_unparse (old->info->fcn->mods)),
01417 uentry_whereSpecified (old));
01418 }
01419 }
01420
01421 return;
01422 }
01423
01424 sRefSet_allElements (newMods, current)
01425 {
01426 if (sRef_isValid (current))
01427 {
01428 sRef rb = sRef_getRootBase (current);
01429
01430 if (sRef_isFileStatic (rb))
01431 {
01432 if (!modInternal)
01433 {
01434 if (!sRefSet_isSameMember (old->info->fcn->mods,
01435 sRef_makeInternalState ())
01436 && !sRefSet_isSameMember (old->info->fcn->mods,
01437 sRef_makeSpecState ()))
01438 {
01439 if (mustConform
01440 && !uentry_isStatic (old)
01441 && optgenerror
01442 (FLG_INCONDEFS,
01443 message
01444 ("Modifies list for %q includes internal state, "
01445 "but %s without modifies internal.",
01446 uentry_getName (old),
01447 uentry_specOrDefName (old)),
01448 uentry_whereLast (unew)))
01449 {
01450 uentry_showWhereSpecified (old);
01451 }
01452
01453 old->info->fcn->mods =
01454 sRefSet_insert (old->info->fcn->mods,
01455 sRef_makeInternalState ());
01456 modInternal = TRUE;
01457 }
01458 }
01459
01460 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
01461 current);
01462 changedMods = TRUE;
01463 }
01464 else
01465 {
01466 if (sRef_canModifyVal (current, old->info->fcn->mods))
01467 {
01468 int size = sRefSet_size (old->info->fcn->mods);
01469
01470 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
01471 current);
01472
01473 if (sRefSet_size (old->info->fcn->mods) != size)
01474 {
01475 changedMods = TRUE;
01476 }
01477 }
01478 else
01479 {
01480 if (mustConform
01481 && optgenerror
01482 (FLG_INCONDEFS,
01483 message
01484 ("Modifies list for %q contains %q, not modifiable "
01485 "according to %s",
01486 uentry_getName (old),
01487 sRef_unparse (current),
01488 uentry_specDeclName (old)),
01489 uentry_whereLast (unew)))
01490 {
01491 uentry_showWhereSpecified (old);
01492 }
01493 }
01494 }
01495 }
01496 } end_sRefSet_allElements;
01497
01498 if (completeConform && uentry_isReallySpecified (old))
01499 {
01500 sRefSet_allElements (old->info->fcn->mods, el)
01501 {
01502 if (sRef_canModify (el, newMods))
01503 {
01504 ;
01505 }
01506 else
01507 {
01508 if (optgenerror
01509 (FLG_NEEDSPEC,
01510 message
01511 ("Specification modifies clause for %q contains %q, "
01512 "not included in declaration modifies clause",
01513 uentry_getName (old),
01514 sRef_unparse (el)),
01515 uentry_whereLast (unew)))
01516 {
01517 uentry_showWhereSpecified (old);
01518 }
01519 }
01520 } end_sRefSet_allElements ;
01521 }
01522
01523
01524
01525
01526
01527 if (changedMods)
01528 {
01529 context_recordFileModifies (old->info->fcn->mods);
01530 }
01531 }
01532
01533 static void
01534 uentry_checkMutableType (uentry ue)
01535 {
01536 ctype ct = uentry_getType (ue);
01537
01538 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
01539 {
01540 voptgenerror (FLG_MUTREP,
01541 message ("Mutable abstract type %q declared without pointer "
01542 "indirection: %t (violates assignment semantics)",
01543 uentry_getName (ue), ct),
01544 uentry_whereDeclared (ue));
01545 }
01546 }
01547
01548 void
01549 uentry_setMutable (uentry e)
01550 {
01551 llassert (uentry_isDatatype (e));
01552 e->info->datatype->mut = YES;
01553 }
01554
01555 static void
01556 uentry_checkIterArgs (uentry ue)
01557 {
01558 bool hasYield = FALSE;
01559 uentryList args;
01560
01561 llassert (uentry_isIter (ue));
01562
01563 args = uentry_getParams (ue);
01564
01565 uentryList_elements (args, el)
01566 {
01567 sstate ds = uentry_getDefState (el);
01568
01569 if (uentry_isYield (el))
01570 {
01571 hasYield = TRUE;
01572 }
01573
01574 if (sstate_isUnknown (ds))
01575 {
01576 uentry_setDefState (el, SS_DEFINED);
01577 }
01578 else
01579 {
01580 ;
01581 }
01582 } end_uentryList_elements;
01583
01584 if (!hasYield)
01585 {
01586 voptgenerror (FLG_HASYIELD,
01587 message ("Iterator %q declared with no yield parameters",
01588 uentry_getName (ue)),
01589 uentry_whereDeclared (ue));
01590 }
01591 }
01592
01593 static chkind
01594 chkind_fromQual (qual qel)
01595 {
01596 if (qual_isChecked (qel))
01597 {
01598 return CH_CHECKED;
01599 }
01600 else if (qual_isCheckMod (qel))
01601 {
01602 return CH_CHECKMOD;
01603 }
01604 else if (qual_isCheckedStrict (qel))
01605 {
01606 return CH_CHECKEDSTRICT;
01607 }
01608 else if (qual_isUnchecked (qel))
01609 {
01610 return CH_UNCHECKED;
01611 }
01612 else
01613 {
01614 BADEXIT;
01615 return CH_UNKNOWN;
01616 }
01617 }
01618
01619 static void
01620 uentry_reflectOtherQualifier ( uentry ue, qual qel)
01621 {
01622 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
01623 {
01624 if (!uentry_isRefCounted (ue))
01625 {
01626 llerror
01627 (FLG_SYNTAX,
01628 message ("Reference counting qualifier %s used on non-reference "
01629 "counted storage: %q",
01630 qual_unparse (qel),
01631 uentry_unparse (ue)));
01632 }
01633 else
01634 {
01635 alkind ak = alkind_fromQual (qel);
01636
01637 uentry_setAliasKind (ue, ak);
01638 }
01639 }
01640 else if (qual_isRefCounted (qel))
01641 {
01642 ctype ct = ctype_realType (uentry_getType (ue));
01643 ctype rt;
01644
01645 if (ctype_isPointer (ct)
01646 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
01647 {
01648
01649 uentryList fields = ctype_getFields (rt);
01650 uentry refs = uentry_undefined;
01651
01652 uentryList_elements (fields, field)
01653 {
01654 if (uentry_isRefsField (field))
01655 {
01656 if (uentry_isValid (refs))
01657 {
01658 llerror
01659 (FLG_SYNTAX,
01660 message ("Reference counted structure type %s has "
01661 "multiple refs fields: %q and %q",
01662 ctype_unparse (ct),
01663 uentry_getName (refs),
01664 uentry_getName (field)));
01665 }
01666
01667 refs = field;
01668 }
01669 } end_uentryList_elements;
01670
01671 if (uentry_isInvalid (refs))
01672 {
01673 vgenhinterror
01674 (FLG_SYNTAX,
01675 message ("Reference counted structure type %s has "
01676 "no refs field",
01677 ctype_unparse (ct)),
01678 cstring_makeLiteral
01679 ("To count reference, the structure must have a field named "
01680 "refs of type int."),
01681 g_currentloc);
01682 }
01683 else if (!ctype_isInt (uentry_getType (refs)))
01684 {
01685 llerror
01686 (FLG_SYNTAX,
01687 message ("Reference counted structure type %s refs field has "
01688 "type %s (should be int)", ctype_unparse (ct),
01689 ctype_unparse (uentry_getType (refs))));
01690 }
01691 else
01692 {
01693 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
01694 uentry_whereDeclared (ue));
01695 }
01696 }
01697 else
01698 {
01699 if ((ctype_isPointer (ct)
01700 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
01701 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
01702 {
01703 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
01704 uentry_whereDeclared (ue));
01705 }
01706 else
01707 {
01708 llerror
01709 (FLG_SYNTAX,
01710 message ("Non-pointer to structure type %s declared with "
01711 "refcounted qualifier",
01712 ctype_unparse (ct)));
01713 }
01714 }
01715 }
01716 else if (qual_isRefs (qel))
01717 {
01718 if (uentry_isVariable (ue) && !uentry_isParam (ue))
01719 {
01720 uentry_setAliasKind (ue, AK_REFS);
01721 }
01722 else
01723 {
01724 llerror
01725 (FLG_SYNTAX,
01726 message ("Refs qualifier used on non-structure field: %q",
01727 uentry_unparse (ue)));
01728 }
01729 }
01730 else if (qual_isAliasQual (qel))
01731 {
01732 alkind ak = alkind_fromQual (qel);
01733 bool okay = TRUE;
01734 alkind oldak = uentry_getAliasKind (ue);
01735 ctype ut = uentry_getType (ue);
01736
01737 if (alkind_isImplicit (ak)
01738 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
01739 {
01740
01741 okay = FALSE;
01742 }
01743
01744 if (uentry_isEitherConstant (ue))
01745 {
01746 llerror
01747 (FLG_SYNTAX,
01748 message ("Alias qualifier %s used on constant: %q",
01749 alkind_unparse (ak), uentry_unparse (ue)));
01750 okay = FALSE;
01751 }
01752
01753 if (ctype_isFunction (ut))
01754 {
01755 ut = ctype_returnValue (ut);
01756 }
01757
01758 if (!(ctype_isVisiblySharable (ut)
01759 || ctype_isRealArray (ut)
01760 || ctype_isRealSU (ut)))
01761 {
01762 if (!qual_isImplied (qel))
01763 {
01764 llerror
01765 (FLG_SYNTAX,
01766 message ("Alias qualifier %s used on unsharable storage type %t: %q",
01767 alkind_unparse (ak), ut, uentry_getName (ue)));
01768 }
01769
01770 okay = FALSE;
01771 }
01772 else
01773 {
01774 if (uentry_isRefCounted (ue))
01775 {
01776 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
01777 || qual_isExposed (qel)
01778 || qual_isObserver (qel)))
01779 {
01780 if (!qual_isImplied (qel))
01781 {
01782 llerror
01783 (FLG_SYNTAX,
01784 message
01785 ("Alias qualifier %s used on reference counted storage: %q",
01786 alkind_unparse (ak),
01787 uentry_unparse (ue)));
01788 }
01789
01790 okay = FALSE;
01791 }
01792 }
01793 else
01794 {
01795 if (qual_isRefQual (qel))
01796 {
01797 llerror
01798 (FLG_SYNTAX,
01799 message ("Qualifier %s used on non-reference counted storage: %q",
01800 alkind_unparse (ak), uentry_unparse (ue)));
01801
01802 okay = FALSE;
01803 }
01804 }
01805 }
01806
01807 if (okay)
01808 {
01809 uentry_setAliasKind (ue, ak);
01810 }
01811 }
01812 else if (qual_isNull (qel))
01813 {
01814 if (uentry_isConstant (ue))
01815 {
01816 sRef_setNullState
01817 (ue->sref,
01818 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
01819 uentry_whereDeclared (ue));
01820 }
01821 else
01822 {
01823 uentry_setNullState (ue, NS_POSNULL);
01824 }
01825 }
01826 else if (qual_isRelNull (qel))
01827 {
01828 uentry_setNullState (ue, NS_RELNULL);
01829 }
01830 else if (qual_isNotNull (qel))
01831 {
01832 uentry_setNullState (ue, NS_MNOTNULL);
01833 }
01834 else if (qual_isAbstract (qel)
01835 || qual_isConcrete (qel))
01836 {
01837 if (!uentry_isDatatype (ue))
01838 {
01839 llerror
01840 (FLG_SYNTAX,
01841 message ("Qualifier %s used with non-datatype",
01842 qual_unparse (qel)));
01843 }
01844 else
01845 {
01846 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
01847 }
01848 }
01849 else if (qual_isMutable (qel))
01850 {
01851 if (!uentry_isDatatype (ue))
01852 {
01853 llerror (FLG_SYNTAX,
01854 message ("Qualifier %s used with non-datatype", qual_unparse (qel)));
01855 }
01856 else
01857 {
01858 if (!ynm_isOn (ue->info->datatype->mut))
01859 {
01860 uentry_checkMutableType (ue);
01861 }
01862
01863 ue->info->datatype->mut = YES;
01864 }
01865 }
01866 else if (qual_isImmutable (qel))
01867 {
01868 if (!uentry_isDatatype (ue))
01869 {
01870 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-datatype",
01871 qual_unparse (qel)));
01872 }
01873 else
01874 {
01875 ue->info->datatype->mut = NO;
01876 }
01877 }
01878 else if (qual_isNullPred (qel))
01879 {
01880 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
01881 {
01882 uentry_makeVarFunction (ue);
01883 }
01884
01885 if (uentry_isFunction (ue))
01886 {
01887 ctype typ = uentry_getType (ue);
01888 ctype rtype = ctype_returnValue (uentry_getType (ue));
01889
01890 if (ctype_isRealBool (rtype))
01891 {
01892 uentryList pl = ctype_argsFunction (typ);
01893
01894 if (uentryList_size (pl) == 1)
01895 {
01896 ue->info->fcn->nullPred = qel;
01897 }
01898 else
01899 {
01900 llerror (FLG_SYNTAX,
01901 message ("Qualifier %s used with function having %d "
01902 "arguments (should have 1)",
01903 qual_unparse (qel),
01904 uentryList_size (pl)));
01905 }
01906 }
01907 else
01908 {
01909 llerror (FLG_SYNTAX,
01910 message ("Qualifier %s used with function returning %s "
01911 "(should return bool)",
01912 qual_unparse (qel),
01913 ctype_unparse (rtype)));
01914 }
01915 }
01916 else
01917 {
01918 llerror (FLG_SYNTAX,
01919 message ("Qualifier %s used with non-function",
01920 qual_unparse (qel)));
01921 }
01922 }
01923 else if (qual_isExitQual (qel))
01924 {
01925 exitkind exk = exitkind_fromQual (qel);
01926
01927 if (uentry_isFunction (ue))
01928 {
01929 if (exitkind_isKnown (ue->info->fcn->exitCode))
01930 {
01931 llerror (FLG_SYNTAX,
01932 message ("Multiple exit qualifiers used on function %q: %s, %s",
01933 uentry_getName (ue),
01934 exitkind_unparse (ue->info->fcn->exitCode),
01935 exitkind_unparse (exk)));
01936 }
01937
01938 ue->info->fcn->exitCode = exk;
01939 }
01940 else
01941 {
01942 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
01943 {
01944 uentry_makeVarFunction (ue);
01945 ue->info->fcn->exitCode = exk;
01946 }
01947 else
01948 {
01949 llerror (FLG_SYNTAX,
01950 message ("Exit qualifier %s used with non-function (type %s)",
01951 qual_unparse (qel),
01952 ctype_unparse (uentry_getType (ue))));
01953 }
01954 }
01955 }
01956 else
01957 {
01958 if (qual_isCQual (qel))
01959 {
01960 ;
01961 }
01962 else
01963 {
01964 llbug (message ("unhandled qualifier: %s", qual_unparse (qel)));
01965 }
01966 }
01967 }
01968
01969 void
01970 uentry_reflectQualifiers (uentry ue, qualList q)
01971 {
01972 llassert (uentry_isValid (ue));
01973
01974 qualList_elements (q, qel)
01975 {
01976 if (qual_isStatic (qel))
01977 {
01978 uentry_setStatic (ue);
01979 }
01980 else if (qual_isUnused (qel))
01981 {
01982 uentry_setUsed (ue, fileloc_undefined);
01983 }
01984 else if (qual_isExternal (qel))
01985 {
01986 fileloc_free (ue->whereDefined);
01987 ue->whereDefined = fileloc_createExternal ();
01988 }
01989 else if (qual_isSef (qel))
01990 {
01991 if (uentry_isVariable (ue))
01992 {
01993 vkind vk = ue->info->var->kind;
01994
01995 llassert (vk != VKREFPARAM);
01996
01997 if (vk == VKYIELDPARAM)
01998 {
01999 llerror
02000 (FLG_SYNTAX,
02001 message ("Qualifier sef cannot be used with %s: %q",
02002 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
02003 uentry_unparse (ue)));
02004 }
02005 else if (vk == VKRETPARAM)
02006 {
02007 ue->info->var->kind = VKSEFRETPARAM;
02008 }
02009 else
02010 {
02011 ue->info->var->kind = VKSEFPARAM;
02012 }
02013 }
02014 else
02015 {
02016 llerror
02017 (FLG_SYNTAX,
02018 message ("Qualifier sef is meaningful only on parameters: %q",
02019 uentry_unparse (ue)));
02020 }
02021 }
02022 else if (qual_isExtern (qel))
02023 {
02024 ue->storageclass = SCEXTERN;
02025 }
02026 else if (qual_isGlobalQual (qel))
02027 {
02028 if (uentry_isVariable (ue))
02029 {
02030 sstate oldstate = ue->info->var->defstate;
02031 sstate defstate = sstate_fromQual (qel);
02032
02033
02034 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
02035 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
02036 {
02037 defstate = SS_UNDEFKILLED;
02038 }
02039 else
02040 {
02041 ;
02042 }
02043
02044 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
02045 ue->info->var->defstate = defstate;
02046 }
02047 else
02048 {
02049 llerror
02050 (FLG_SYNTAX,
02051 message ("Qualifier %s used on non-variable: %q",
02052 qual_unparse (qel), uentry_unparse (ue)));
02053 }
02054 }
02055 else if (qual_isAllocQual (qel))
02056 {
02057 ctype realType = ctype_realType (ue->utype);
02058 sstate defstate = sstate_fromQual (qel);
02059
02060 if (ctype_isFunction (realType))
02061 {
02062 realType = ctype_realType (ctype_returnValue (realType));
02063 }
02064
02065 if (qual_isRelDef (qel))
02066 {
02067 ;
02068 }
02069 else
02070 {
02071 if (!ctype_isAP (realType)
02072 && !ctype_isSU (realType)
02073 && !ctype_isUnknown (realType)
02074 && !ctype_isAbstract (ue->utype))
02075 {
02076 llerror
02077 (FLG_SYNTAX,
02078 message ("Qualifier %s used on non-pointer or struct: %q",
02079 qual_unparse (qel), uentry_unparse (ue)));
02080 }
02081 }
02082
02083 uentry_setDefState (ue, defstate);
02084
02085 if (sRef_isStateSpecial (ue->sref)
02086 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
02087 {
02088 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
02089 }
02090 }
02091 else if (qual_isYield (qel))
02092 {
02093 if (uentry_isVariable (ue))
02094 {
02095 ue->info->var->kind = VKYIELDPARAM;
02096 }
02097 else
02098 {
02099 llerror
02100 (FLG_SYNTAX,
02101 message ("Qualifier %s used on non-iterator parameter: %q",
02102 qual_unparse (qel), uentry_unparse (ue)));
02103 }
02104 }
02105 else if (qual_isExQual (qel))
02106 {
02107 exkind ek = exkind_fromQual (qel);
02108 ctype ut = uentry_getType (ue);
02109
02110 if (ctype_isFunction (ut))
02111 {
02112 ut = ctype_returnValue (ut);
02113 }
02114
02115 if (!(ctype_isVisiblySharable (ut))
02116 && !(ctype_isArray (ut))
02117 && !(ctype_isStruct (ctype_realType (ut))))
02118 {
02119 if (!qual_isImplied (qel))
02120 {
02121 llerror
02122 (FLG_SYNTAX,
02123 message ("Qualifier %s used on unsharable storage type %t: %q",
02124 exkind_unparse (ek), ut, uentry_getName (ue)));
02125 }
02126 }
02127 else
02128 {
02129 alkind ak = sRef_getAliasKind (ue->sref);
02130
02131 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
02132
02133 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
02134 {
02135 if (!alkind_isTemp (ak))
02136 {
02137 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
02138 }
02139 }
02140 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
02141 || alkind_isOwned (ak))
02142 {
02143 ;
02144 }
02145 else
02146 {
02147 llerror
02148 (FLG_SYNTAX,
02149 message ("Exposure qualifier %s used on %s storage (should "
02150 "be dependent): %q",
02151 qual_unparse (qel),
02152 alkind_unparse (ak),
02153 uentry_unparse (ue)));
02154 }
02155 }
02156 }
02157 else if (qual_isGlobCheck (qel))
02158 {
02159 if (uentry_isVariable (ue))
02160 {
02161 chkind ch = chkind_fromQual (qel);
02162
02163 if (ue->info->var->checked != CH_UNKNOWN)
02164 {
02165 if (ch == ue->info->var->checked)
02166 {
02167 llerror (FLG_SYNTAX,
02168 message ("Redundant %s qualifier on %q",
02169 qual_unparse (qel),
02170 uentry_getName (ue)));
02171 }
02172 else
02173 {
02174 llerror (FLG_SYNTAX,
02175 message
02176 ("Contradictory %s and %s qualifiers on %q",
02177 qual_unparse (qel),
02178 checkedName (ue->info->var->checked),
02179 uentry_getName (ue)));
02180 }
02181 }
02182
02183 ue->info->var->checked = ch;
02184 }
02185 else
02186 {
02187 llerror
02188 (FLG_SYNTAX,
02189 message ("Qualifier %s used with non-variable",
02190 qual_unparse (qel)));
02191 }
02192 }
02193 else if (qual_isReturned (qel))
02194 {
02195 if (uentry_isVariable (ue))
02196 {
02197 ue->info->var->kind = VKRETPARAM;
02198 }
02199 else
02200 {
02201 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
02202 qual_unparse (qel)));
02203 }
02204 }
02205 else
02206 {
02207 uentry_reflectOtherQualifier (ue, qel);
02208 }
02209
02210 sRef_storeState (ue->sref);
02211 } end_qualList_elements;
02212
02213 qualList_clear (q);
02214 }
02215
02216 bool
02217 uentry_isOnly (uentry ue)
02218 {
02219 return (!uentry_isUndefined (ue)
02220 && uentry_isVariable (ue)
02221 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
02222 }
02223
02224 static void
02225 uentry_setAliasKind ( uentry ue, alkind ak)
02226 {
02227 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
02228 sRef_setOrigAliasKind (ue->sref, ak);
02229 }
02230
02231 static void
02232 uentry_setNullState ( uentry ue, nstate ns)
02233 {
02234 if (uentry_isVariable (ue))
02235 {
02236 ue->info->var->nullstate = ns;
02237 }
02238
02239 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
02240 }
02241
02242 bool
02243 uentry_isUnique (uentry ue)
02244 {
02245 return (!uentry_isUndefined (ue)
02246 && uentry_isVariable (ue)
02247 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
02248 }
02249
02250 bool
02251 uentry_isFileStatic (uentry ue)
02252 {
02253 return (uentry_isStatic (ue)
02254 && (!uentry_isVariable (ue)
02255 || sRef_isFileStatic (uentry_getSref (ue))));
02256 }
02257
02258 bool
02259 uentry_isExported (uentry ue)
02260 {
02261 if (uentry_isValid (ue))
02262 {
02263 if (uentry_isVariable (ue))
02264 {
02265 return (sRef_isRealGlobal (uentry_getSref (ue)));
02266 }
02267 else
02268 {
02269 return !uentry_isStatic (ue);
02270 }
02271 }
02272
02273 return FALSE;
02274 }
02275
02276 bool
02277 uentry_isNonLocal (uentry ue)
02278 {
02279 return (uentry_isValid (ue) && uentry_isVariable (ue)
02280 && (sRef_isGlobal (ue->sref) || uentry_isStatic (ue)));
02281 }
02282
02283 bool
02284 uentry_isGlobal (uentry ue)
02285 {
02286 return (uentry_isValid (ue) && uentry_isVariable (ue) &&
02287 sRef_isGlobal (ue->sref));
02288 }
02289
02290 bool
02291 uentry_isPrintfLike (uentry ue)
02292 {
02293 return (uentry_isFunction (ue)
02294 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
02295 }
02296
02297 bool
02298 uentry_isScanfLike (uentry ue)
02299 {
02300 return (uentry_isFunction (ue)
02301 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
02302 }
02303
02304 bool
02305 uentry_isMessageLike (uentry ue)
02306 {
02307 return (uentry_isFunction (ue)
02308 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
02309 }
02310
02311 static void checkSpecialFunction ( uentry ue)
02312 {
02313 uentryList args = uentry_getParams (ue);
02314
02315 if (!uentryList_isMissingParams (args))
02316 {
02317 uentry last = uentry_undefined;
02318
02319 uentryList_elements (args, current)
02320 {
02321 if (uentry_isElipsisMarker (current))
02322 {
02323 if (uentry_isUndefined (last))
02324 {
02325 voptgenerror
02326 (FLG_SYNTAX,
02327 message ("Function %q is marked %s, but has no format "
02328 "string argument before elipsis",
02329 uentry_getName (ue),
02330 specCode_unparse (ue->info->fcn->specialCode)),
02331 uentry_whereLast (ue));
02332 ue->info->fcn->specialCode = SPC_NONE;
02333 }
02334 else
02335 {
02336 ctype rt = ctype_realType (uentry_getType (last));
02337
02338 if (!ctype_match (rt, ctype_string))
02339 {
02340 bool okay = FALSE;
02341
02342
02343 if (ctype_isAP (rt))
02344 {
02345 ctype base = ctype_baseArrayPtr (rt);
02346
02347 if (ctype_isArbitraryIntegral (base))
02348 {
02349 okay = TRUE;
02350 }
02351 }
02352
02353 if (!okay)
02354 {
02355 voptgenerror
02356 (FLG_SYNTAX,
02357 message ("Function %q is marked %s, but the argument "
02358 "before the elipsis has type %s (should be char *)",
02359 uentry_getName (ue),
02360 specCode_unparse (ue->info->fcn->specialCode),
02361 ctype_unparse (uentry_getType (last))),
02362 uentry_whereLast (ue));
02363
02364 ue->info->fcn->specialCode = SPC_NONE;
02365 }
02366 }
02367 }
02368 return;
02369 }
02370 last = current;
02371 } end_uentryList_elements ;
02372
02373 voptgenerror
02374 (FLG_SYNTAX,
02375 message ("Function %q is marked %s, but has no elipsis parameter",
02376 uentry_getName (ue),
02377 specCode_unparse (ue->info->fcn->specialCode)),
02378 uentry_whereLast (ue));
02379
02380 ue->info->fcn->specialCode = SPC_NONE;
02381 }
02382 }
02383
02384 void
02385 uentry_setPrintfLike (uentry ue)
02386 {
02387 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
02388 {
02389 uentry_makeVarFunction (ue);
02390 }
02391
02392 llassertfatal (uentry_isFunction (ue));
02393 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
02394 checkSpecialFunction (ue);
02395 }
02396
02397 void
02398 uentry_setScanfLike (uentry ue)
02399 {
02400 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
02401 {
02402 uentry_makeVarFunction (ue);
02403 }
02404
02405 llassertfatal (uentry_isFunction (ue));
02406 ue->info->fcn->specialCode = SPC_SCANFLIKE;
02407 checkSpecialFunction (ue);
02408 }
02409
02410 void
02411 uentry_setMessageLike (uentry ue)
02412 {
02413 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
02414 {
02415 uentry_makeVarFunction (ue);
02416 }
02417
02418 llassertfatal (uentry_isFunction (ue));
02419 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
02420 checkSpecialFunction (ue);
02421 }
02422
02423 bool
02424 uentry_isSpecialFunction (uentry ue)
02425 {
02426 return (uentry_isFunction (ue)
02427 && (ue->info->fcn->specialCode != SPC_NONE));
02428 }
02429
02430 uentry uentry_makeParam (idDecl t, int i)
02431 {
02432 ctype ct = idDecl_getCtype (t);
02433 ctype base = ct;
02434 sRef pref = sRef_makeParam (i, ct);
02435 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
02436
02437 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
02438 uentry_implicitParamAnnots (ue);
02439
02440
02441
02442 while (ctype_isFixedArray (base)) {
02443 base = ctype_baseArrayPtr (base);
02444 }
02445
02446 if (ctype_isIncompleteArray (base)) {
02447 base = ctype_baseArrayPtr (base);
02448
02449 if (ctype_isArray (base)) {
02450 if (!uentry_hasName (ue)) {
02451 (void) optgenerror (FLG_INCOMPLETETYPE,
02452 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
02453 i + 1,
02454 ctype_unparse (ct)),
02455 uentry_whereLast (ue));
02456 } else {
02457 (void) optgenerror (FLG_INCOMPLETETYPE,
02458 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
02459 uentry_getName (ue),
02460 ctype_unparse (ct)),
02461 uentry_whereLast (ue));
02462 }
02463 }
02464 }
02465
02466 return ue;
02467 }
02468
02469 uentry uentry_makeIdVariable (idDecl t)
02470 {
02471 ctype ct = idDecl_getCtype (t);
02472
02473 if (ctype_isFunction (ct))
02474 {
02475 return (uentry_makeIdFunction (t));
02476 }
02477 else
02478 {
02479 fileloc loc = setLocation ();
02480 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
02481
02482 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
02483
02484 if (!uentry_isExtern (ue))
02485 {
02486 uentry_setDefined (ue, loc);
02487 }
02488
02489 return ue;
02490 }
02491 }
02492
02493 # ifndef NOLCL
02494 uentry uentry_makeVariableParam (cstring n, ctype t)
02495 {
02496 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
02497 }
02498 # endif
02499
02500
02501
02502
02503
02504
02505 uentry uentry_makeConstantAux (cstring n, ctype t,
02506 fileloc f, bool priv,
02507 multiVal m)
02508 {
02509 uentry e = uentry_alloc ();
02510
02511 e->ukind = KCONST;
02512 e->uname = cstring_copy (n);
02513 e->utype = t;
02514 e->storageclass = SCNONE;
02515
02516 e->sref = sRef_makeConst (t);
02517
02518 e->lset = FALSE;
02519 e->used = FALSE;
02520
02521 e->uses = filelocList_new ();
02522 e->isPrivate = priv;
02523 e->hasNameError = FALSE;
02524
02525 e->info = (uinfo) dmalloc (sizeof (*e->info));
02526 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
02527 e->info->uconst->val = m;
02528 e->info->uconst->access = typeIdSet_undefined;
02529
02530 uentry_setSpecDef (e, f);
02531
02532 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
02533 {
02534 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
02535 }
02536
02537 return (e);
02538 }
02539
02540 uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
02541 {
02542 return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
02543 }
02544
02545 uentry uentry_makeIdConstant (idDecl t)
02546 {
02547 uentry ue = uentry_makeConstant (idDecl_observeId (t),
02548 idDecl_getCtype (t),
02549 fileloc_undefined);
02550
02551 llassert (fileloc_isUndefined (ue->whereDeclared));
02552 ue->whereDeclared = setLocation ();
02553
02554 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
02555
02556 return ue;
02557 }
02558
02559
02560
02561
02562
02563 void uentry_setDefState (uentry ue, sstate defstate)
02564 {
02565 if (uentry_isValid (ue))
02566 {
02567 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
02568
02569 if (uentry_isVariable (ue))
02570 {
02571 ue->info->var->defstate = defstate;
02572 }
02573 }
02574 }
02575
02576 bool uentry_isCheckedUnknown (uentry ue)
02577 {
02578 return (uentry_isVar (ue)
02579 && (ue->info->var->checked == CH_UNKNOWN));
02580 }
02581
02582 bool uentry_isCheckMod (uentry ue)
02583 {
02584 return (uentry_isVar (ue)
02585 && (ue->info->var->checked == CH_CHECKMOD));
02586 }
02587
02588 bool uentry_isUnchecked (uentry ue)
02589 {
02590 return (uentry_isVar (ue)
02591 && (ue->info->var->checked == CH_UNCHECKED));
02592 }
02593
02594 bool uentry_isChecked (uentry ue)
02595 {
02596 return (uentry_isVar (ue)
02597 && (ue->info->var->checked == CH_CHECKED));
02598 }
02599
02600 bool uentry_isCheckedModify (uentry ue)
02601 {
02602 return (uentry_isVar (ue)
02603 && (ue->info->var->checked == CH_CHECKED
02604 || ue->info->var->checked == CH_CHECKMOD
02605 || ue->info->var->checked == CH_CHECKEDSTRICT));
02606 }
02607
02608 bool uentry_isCheckedStrict (uentry ue)
02609 {
02610 return (uentry_isVar (ue)
02611 && (ue->info->var->checked == CH_CHECKEDSTRICT));
02612 }
02613
02614 void uentry_setUnchecked (uentry ue)
02615 {
02616 llassert (uentry_isVar (ue));
02617
02618 ue->info->var->checked = CH_UNCHECKED;
02619 }
02620
02621 void uentry_setChecked (uentry ue)
02622 {
02623 llassert (uentry_isVar (ue));
02624
02625 ue->info->var->checked = CH_CHECKED;
02626 }
02627
02628 void uentry_setCheckMod (uentry ue)
02629 {
02630 llassert (uentry_isVar (ue));
02631
02632 ue->info->var->checked = CH_CHECKMOD;
02633 }
02634
02635 void uentry_setCheckedStrict (uentry ue)
02636 {
02637 llassert (uentry_isVar (ue));
02638
02639 ue->info->var->checked = CH_CHECKEDSTRICT;
02640 }
02641
02642 static
02643 uentry uentry_makeVariableAux (cstring n, ctype t,
02644 fileloc f,
02645 sRef s,
02646 bool priv, vkind kind)
02647 {
02648 uentry e = uentry_alloc ();
02649 ctype rt = t;
02650
02651 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
02652
02653 e->ukind = KVAR;
02654 e->uname = cstring_copy (n);
02655 e->utype = t;
02656
02657 e->storageclass = SCNONE;
02658
02659 e->sref = s;
02660
02661 e->used = FALSE;
02662 e->lset = FALSE;
02663
02664 e->uses = filelocList_new ();
02665 e->isPrivate = priv;
02666 e->hasNameError = FALSE;
02667
02668 e->info = (uinfo) dmalloc (sizeof (*e->info));
02669 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
02670 e->info->var->kind = kind;
02671
02672 e->info->var->checked = CH_UNKNOWN;
02673
02674 uentry_setSpecDef (e, f);
02675
02676 if (ctype_isFunction (rt))
02677 {
02678 rt = ctype_returnValue (rt);
02679 }
02680
02681 if (ctype_isUA (rt))
02682 {
02683 sRef_setStateFromType (e->sref, rt);
02684 }
02685
02686 e->info->var->defstate = sRef_getDefState (e->sref);
02687 e->info->var->nullstate = sRef_getNullState (e->sref);
02688
02689 return (e);
02690 }
02691
02692 bool
02693 uentry_isYield (uentry ue)
02694 {
02695 return (uentry_isVariable (ue)
02696 && (ue->info->var->kind == VKYIELDPARAM
02697 || ue->info->var->kind == VKREFYIELDPARAM));
02698 }
02699
02700 static bool
02701 uentry_isRefsField (uentry ue)
02702 {
02703 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
02704 }
02705
02706
02707 uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
02708 {
02709 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
02710 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
02711 }
02712
02713
02714
02715
02716
02717 void uentry_makeVarFunction (uentry ue)
02718 {
02719 alkind ak;
02720 exkind ek;
02721 uvinfo oldInfo;
02722 fileloc loc;
02723
02724 llassert (uentry_isValid (ue));
02725 llassert (!sRef_modInFunction ());
02726
02727 ak = sRef_getOrigAliasKind (ue->sref);
02728 ek = sRef_getOrigExKind (ue->sref);
02729
02730 oldInfo = ue->info->var;
02731
02732 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
02733
02734
02735
02736
02737
02738 ue->used |= (oldInfo->kind == VKEXPMACRO);
02739
02740 ue->ukind = KFCN;
02741 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
02742 ue->info->fcn->exitCode = XK_UNKNOWN;
02743 ue->info->fcn->nullPred = QU_UNKNOWN;
02744 ue->info->fcn->specialCode = SPC_NONE;
02745 ue->info->fcn->access = typeIdSet_undefined;
02746 ue->info->fcn->hasGlobs = FALSE;
02747 ue->info->fcn->globs = globSet_undefined;
02748 ue->info->fcn->hasMods = FALSE;
02749 ue->info->fcn->mods = sRefSet_undefined;
02750 ue->info->fcn->specclauses = NULL;
02751 ue->info->fcn->defparams = uentryList_undefined;
02752
02753 if (ctype_isFunction (ue->utype))
02754 {
02755 ue->sref = sRef_makeType (ctype_returnValue (ue->utype));
02756 }
02757 else
02758 {
02759 ue->sref = sRef_makeType (ctype_unknown);
02760 }
02761
02762 if (sRef_isRefCounted (ue->sref))
02763 {
02764 ak = AK_NEWREF;
02765 }
02766 else
02767 {
02768 if (alkind_isUnknown (ak))
02769 {
02770 if (exkind_isKnown (ek))
02771 {
02772 ak = AK_IMPDEPENDENT;
02773 }
02774 else
02775 {
02776 if (context_getFlag (FLG_RETIMPONLY))
02777 {
02778 if (ctype_isFunction (ue->utype)
02779 && ctype_isVisiblySharable
02780 (ctype_realType (ctype_returnValue (ue->utype))))
02781 {
02782 if (uentryList_hasReturned (uentry_getParams (ue)))
02783 {
02784 ;
02785 }
02786 else
02787 {
02788 ak = AK_IMPONLY;
02789 }
02790 }
02791 }
02792 }
02793 }
02794 }
02795
02796 loc = ue->whereDeclared;
02797
02798 sRef_setAliasKind (ue->sref, ak, loc);
02799 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
02800 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
02801 sRef_setExKind (ue->sref, ek, loc);
02802
02803 if (oldInfo->kind == VKEXPMACRO)
02804 {
02805 fileloc_free (loc);
02806 ue->whereDeclared = fileloc_undefined;
02807 }
02808 else
02809 {
02810 fileloc_free (ue->whereDefined);
02811 ue->whereDefined = fileloc_undefined;
02812 }
02813
02814 uvinfo_free (oldInfo);
02815 }
02816
02817 void
02818 uentry_setGlobals (uentry ue, globSet globs)
02819 {
02820 llassert (uentry_isValid (ue));
02821
02822 if (uentry_isIter (ue))
02823 {
02824 llassert (globSet_isUndefined (ue->info->iter->globs));
02825 ue->info->iter->globs = globs;
02826 }
02827 else
02828 {
02829 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
02830 {
02831 uentry_makeVarFunction (ue);
02832 }
02833
02834 llassert (uentry_isFunction (ue));
02835 llassert (!ue->info->fcn->hasGlobs
02836 && globSet_isUndefined (ue->info->fcn->globs));
02837
02838 ue->info->fcn->hasGlobs = TRUE;
02839 ue->info->fcn->globs = globs;
02840
02841 }
02842
02843 if (globSet_hasStatic (globs))
02844 {
02845 context_recordFileGlobals (globs);
02846 }
02847
02848 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
02849 {
02850 ue->info->fcn->hasMods = TRUE;
02851 }
02852 }
02853
02854 void uentry_addAccessType (uentry ue, typeId tid)
02855 {
02856 if (uentry_isFunction (ue))
02857 {
02858 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
02859 }
02860 else if (uentry_isEitherConstant (ue))
02861 {
02862 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
02863 }
02864 else if (uentry_isIter (ue))
02865 {
02866 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
02867 }
02868 else if (uentry_isEndIter (ue))
02869 {
02870 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
02871 }
02872 else
02873 {
02874 llbug (message ("no access for: %q", uentry_unparse (ue)));
02875 }
02876 }
02877
02878 uentry
02879 uentry_makeFunction (cstring n, ctype t,
02880 typeId access,
02881 globSet globs, sRefSet mods,
02882 fileloc f)
02883 {
02884 return (uentry_makeFunctionAux (n, t,
02885 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
02886 : typeIdSet_single (access)),
02887 globs, mods, f,
02888 FALSE, FALSE));
02889 }
02890
02891 # ifndef NOLCL
02892 uentry
02893 uentry_makePrivFunction2 (cstring n, ctype t,
02894 typeIdSet access,
02895 globSet globs, sRefSet mods,
02896 fileloc f)
02897 {
02898 return (uentry_makeFunctionAux (n, t, access, globs, mods, f, TRUE, FALSE));
02899 }
02900
02901
02902 uentry
02903 uentry_makeSpecFunction (cstring n, ctype t,
02904 typeIdSet access,
02905 globSet globs,
02906 sRefSet mods,
02907 fileloc f)
02908 {
02909 uentry ue = uentry_makeFunctionAux (n, t, access,
02910 globs, mods, f,
02911 FALSE, FALSE);
02912
02913 uentry_setHasGlobs (ue);
02914 uentry_setHasMods (ue);
02915
02916 reflectImplicitFunctionQualifiers (ue, TRUE);
02917 return (ue);
02918 }
02919 # endif
02920
02921 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
02922 {
02923 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
02924 sRef_undefined, FALSE, VKEXPMACRO);
02925
02926 uentry_setDefined (ue, f);
02927 return ue;
02928 }
02929
02930 uentry
02931 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
02932 {
02933 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
02934 typeIdSet_singleOpt (access),
02935 globSet_undefined, sRefSet_undefined,
02936 fileloc_undefined,
02937 FALSE, TRUE);
02938
02939 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
02940 return ue;
02941 }
02942
02943 bool uentry_isForward (uentry e)
02944 {
02945 if (uentry_isValid (e))
02946 {
02947 ctype ct = uentry_getType (e);
02948
02949 return (ctype_isUnknown (ct)
02950 || (ctype_isFunction (ct)
02951 && ctype_isUnknown (ctype_returnValue (ct))));
02952 }
02953
02954 return FALSE;
02955 }
02956
02957 # ifndef NOLCL
02958 uentry
02959 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
02960 {
02961 return (uentry_makeFunctionAux (n, ctype_unknown, access,
02962 globSet_new (),
02963 sRefSet_new (), f,
02964 FALSE, TRUE));
02965 }
02966
02967 uentry
02968 uentry_makeUnspecFunction (cstring n, ctype t,
02969 typeIdSet access,
02970 fileloc f)
02971 {
02972 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_new (),
02973 sRefSet_new (), f, FALSE, TRUE);
02974
02975 reflectImplicitFunctionQualifiers (ue, TRUE);
02976 return ue;
02977 }
02978 # endif
02979
02980
02981
02982
02983
02984
02985
02986 uentry
02987 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abs,
02988 fileloc f, bool priv)
02989 {
02990 uentry e = uentry_alloc ();
02991
02992
02993 e->ukind = KDATATYPE;
02994 e->uname = cstring_copy (n);
02995 e->utype = t;
02996 e->storageclass = SCNONE;
02997 e->sref = sRef_makeUnknown ();
02998
02999 if (ctype_isUA (t))
03000 {
03001 sRef_setStateFromType (e->sref, t);
03002 }
03003
03004 uentry_setSpecDef (e, f);
03005
03006 e->uses = filelocList_new ();
03007 e->isPrivate = priv;
03008 e->hasNameError = FALSE;
03009
03010 e->used = FALSE;
03011 e->lset = FALSE;
03012
03013 e->info = (uinfo) dmalloc (sizeof (*e->info));
03014 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
03015 e->info->datatype->abs = abs;
03016 e->info->datatype->mut = mut;
03017 e->info->datatype->type = ctype_undefined;
03018
03019 if (uentry_isDeclared (e))
03020 {
03021 uentry_setDefined (e, f);
03022 }
03023
03024 if (ynm_isOn (abs) && !(uentry_isCodeDefined (e)))
03025 {
03026 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
03027 }
03028
03029 return (e);
03030 }
03031
03032 uentry
03033 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abs,
03034 fileloc f)
03035 {
03036 return (uentry_makeDatatypeAux (n, t, mut, abs, f, FALSE));
03037 }
03038
03039 uentry uentry_makeBoolDatatype (ynm abs)
03040 {
03041 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
03042 ctype_bool, NO, abs,
03043 fileloc_getBuiltin (),
03044 FALSE);
03045
03046 ret->info->datatype->type = ctype_bool;
03047 return ret;
03048 }
03049
03050
03051
03052
03053
03054 static uentry
03055 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
03056 fileloc f)
03057 {
03058 uentry e = uentry_alloc ();
03059
03060 e->ukind = KITER;
03061 e->uname = cstring_copy (n);
03062 e->utype = ct;
03063 e->sref = sRef_makeUnknown ();
03064 e->storageclass = SCNONE;
03065 e->used = FALSE;
03066 e->lset = FALSE;
03067
03068 uentry_setSpecDef (e, f);
03069
03070 e->uses = filelocList_new ();
03071 e->isPrivate = FALSE;
03072 e->hasNameError = FALSE;
03073
03074 e->info = (uinfo) dmalloc (sizeof (*e->info));
03075 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
03076 e->info->iter->access = access;
03077 e->info->iter->mods = sRefSet_undefined;
03078 e->info->iter->globs = globSet_undefined;
03079
03080 uentry_checkIterArgs (e);
03081 return (e);
03082 }
03083
03084 uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
03085 {
03086 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
03087 }
03088
03089 static uentry
03090 uentry_makeEndIterAux (cstring n, typeIdSet access, fileloc f)
03091 {
03092 uentry e = uentry_alloc ();
03093
03094
03095 e->ukind = KENDITER;
03096 e->storageclass = SCNONE;
03097 e->uname = message ("end_%s", n);
03098 e->utype = ctype_unknown;
03099 e->sref = sRef_makeUnknown ();
03100
03101 uentry_setSpecDef (e, f);
03102
03103 e->used = FALSE;
03104 e->lset = FALSE;
03105
03106 e->uses = filelocList_new ();
03107 e->isPrivate = FALSE;
03108 e->hasNameError = FALSE;
03109
03110 e->info = (uinfo) dmalloc (sizeof (*e->info));
03111 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
03112
03113 e->info->enditer->access = access;
03114
03115 return (e);
03116 }
03117
03118 uentry uentry_makeEndIter (cstring n, fileloc f)
03119 {
03120 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
03121 }
03122
03123
03124
03125
03126
03127 static uentry
03128 uentry_makeTagAux (cstring n, ctype t,
03129 fileloc fl,
03130 bool priv, ekind kind)
03131 {
03132 uentry e = uentry_alloc ();
03133
03134 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
03135 {
03136 llbuglit ("uentry_makeTagAux: not a tag type");
03137 }
03138
03139 e->ukind = kind;
03140
03141 e->uname = cstring_copy (n);
03142
03143 e->utype = t;
03144 e->sref = sRef_makeUnknown ();
03145 e->storageclass = SCNONE;
03146
03147 uentry_setSpecDef (e, fl);
03148
03149 e->used = FALSE;
03150 e->lset = FALSE;
03151
03152 e->uses = filelocList_new ();
03153 e->isPrivate = priv;
03154 e->hasNameError = FALSE;
03155
03156 e->info = (uinfo) dmalloc (sizeof (*e->info));
03157 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
03158 e->info->datatype->abs = NO;
03159 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
03160 e->info->datatype->type = t;
03161
03162 if (uentry_isDeclared (e))
03163 {
03164 uentry_setDefined (e, fl);
03165 }
03166
03167 return (e);
03168 }
03169
03170 uentry uentry_makeStructTagLoc (cstring n, ctype t)
03171 {
03172 cstring sname = makeStruct (n);
03173 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
03174
03175 cstring_free (sname);
03176 return (ret);
03177 }
03178
03179 uentry
03180 uentry_makeStructTag (cstring n, ctype t, fileloc loc)
03181 {
03182 cstring sname = makeStruct (n);
03183 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
03184
03185 cstring_free (sname);
03186 return ret;
03187 }
03188
03189 uentry
03190 uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
03191 {
03192 cstring uname = makeUnion (n);
03193 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
03194
03195 cstring_free (uname);
03196 return (ret);
03197 }
03198
03199 # ifndef NOLCL
03200 uentry
03201 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
03202 {
03203 cstring ename = makeEnum (n);
03204 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
03205
03206 cstring_free (ename);
03207 return ret;
03208 }
03209 # endif
03210
03211 uentry
03212 uentry_makeUnionTagLoc (cstring n, ctype t)
03213 {
03214 cstring uname = makeUnion (n);
03215 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
03216
03217 cstring_free (uname);
03218 return ret;
03219 }
03220
03221 uentry
03222 uentry_makeEnumTagLoc (cstring n, ctype t)
03223 {
03224 cstring ename = makeEnum (n);
03225 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
03226
03227 cstring_free (ename);
03228 return ret;
03229 }
03230
03231 bool
03232 uentry_isStructTag (uentry ue)
03233 {
03234 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
03235 }
03236
03237 bool
03238 uentry_isUnionTag (uentry ue)
03239 {
03240 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
03241 }
03242
03243 bool
03244 uentry_isEnumTag (uentry ue)
03245 {
03246 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
03247 }
03248
03249 bool
03250 uentry_isAnyTag (uentry ue)
03251 {
03252 return (uentry_isStructTag (ue)
03253 || uentry_isUnionTag (ue)
03254 || uentry_isEnumTag (ue));
03255 }
03256
03257 static uentry emarker = NULL;
03258
03259 extern void uentry_destroyMod (void)
03260
03261 {
03262 static bool wasDestroyed = FALSE;
03263
03264 llassert (!wasDestroyed);
03265
03266 if (emarker != NULL)
03267 {
03268 uentry_reallyFree (emarker);
03269 }
03270
03271 wasDestroyed = TRUE;
03272 }
03273
03274 uentry
03275 uentry_makeElipsisMarker (void)
03276 {
03277 if (emarker == NULL)
03278 {
03279 emarker = uentry_alloc ();
03280
03281 emarker->ukind = KELIPSMARKER;
03282 emarker->uname = cstring_makeLiteral ("...");
03283 emarker->utype = ctype_elipsMarker;
03284 emarker->sref = sRef_undefined;
03285 emarker->storageclass = SCNONE;
03286 emarker->used = FALSE;
03287 emarker->lset = FALSE;
03288 emarker->info = NULL;
03289
03290 uentry_setSpecDef (emarker, fileloc_undefined);
03291 emarker->uses = filelocList_new ();
03292 emarker->isPrivate = FALSE;
03293 emarker->hasNameError = FALSE;
03294 }
03295
03296 return (emarker);
03297 }
03298
03299
03300
03301
03302
03303 bool
03304 uentry_equiv (uentry p1, uentry p2)
03305 {
03306 if (uentry_compare (p1, p2) != 0)
03307 {
03308 return FALSE;
03309 }
03310 else
03311 {
03312 return TRUE;
03313 }
03314 }
03315
03316 int
03317 uentry_xcomparealpha (uentry *p1, uentry *p2)
03318 {
03319 int res;
03320
03321 if ((res = uentry_compare (*p1, *p2)) == 0) {
03322 if ((*p1 != NULL) && (*p2 != NULL)) {
03323 res = cstring_compare ((*p1)->uname,
03324 (*p2)->uname);
03325 }
03326 }
03327
03328 return res;
03329 }
03330
03331 int
03332 uentry_xcompareuses (uentry *p1, uentry *p2)
03333 {
03334 uentry u1 = *p1;
03335 uentry u2 = *p2;
03336
03337 if (uentry_isValid (u1))
03338 {
03339 if (uentry_isValid (u2))
03340 {
03341 return (-1 * int_compare (filelocList_size (u1->uses),
03342 filelocList_size (u2->uses)));
03343 }
03344 else
03345 {
03346 return 1;
03347 }
03348 }
03349 else
03350 {
03351 if (uentry_isValid (u2))
03352 {
03353 return -1;
03354 }
03355 else
03356 {
03357 return 0;
03358 }
03359 }
03360 }
03361
03362 int
03363 uentry_compareStrict (uentry v1, uentry v2)
03364 {
03365 COMPARERETURN (uentry_compare (v1, v2));
03366
03367 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
03368 {
03369 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
03370 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
03371 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
03372 }
03373
03374 return 0;
03375 }
03376
03377 int
03378 uentry_compare (uentry u1, uentry u2)
03379 {
03380 if (u1 == u2) return 0;
03381
03382 if (uentry_isInvalid (u1)) return -1;
03383 if (uentry_isInvalid (u2)) return 1;
03384
03385 INTCOMPARERETURN (u1->ukind, u2->ukind);
03386 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
03387 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
03388
03389 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
03390
03391 switch (u1->ukind)
03392 {
03393 case KINVALID:
03394 case KELIPSMARKER:
03395
03396
03397
03398 return 0;
03399 case KENUMCONST:
03400 case KCONST:
03401 return (multiVal_compare (u1->info->uconst->val,
03402 u2->info->uconst->val));
03403 case KSTRUCTTAG:
03404 case KUNIONTAG:
03405 case KENUMTAG:
03406 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
03407 case KITER:
03408 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
03409 uentry_accessType (u2)));
03410 return (uentryList_compareParams (uentry_getParams (u1),
03411 uentry_getParams (u2)));
03412 case KENDITER:
03413 return (typeIdSet_compare (uentry_accessType (u1),
03414 uentry_accessType (u2)));
03415 case KFCN:
03416 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
03417 uentry_accessType (u2)));
03418 COMPARERETURN (globSet_compare (uentry_getGlobs (u1),
03419 uentry_getGlobs (u2)));
03420 COMPARERETURN (uentryList_compareParams (uentry_getParams (u1),
03421 uentry_getParams (u2)));
03422 COMPARERETURN (generic_compare (u1->info->fcn->specialCode,
03423 u2->info->fcn->specialCode));
03424 COMPARERETURN (generic_compare (u1->info->fcn->nullPred,
03425 u2->info->fcn->nullPred));
03426
03427 return (sRefSet_compare (uentry_getMods (u1), uentry_getMods (u2)));
03428 case KVAR:
03429 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
03430 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
03431 sRef_getOrigAliasKind (u2->sref)));
03432 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
03433 sRef_getOrigExKind (u2->sref)));
03434 COMPARERETURN (generic_compare (u1->info->var->checked,
03435 u2->info->var->checked));
03436 COMPARERETURN (generic_compare (u1->info->var->defstate,
03437 u2->info->var->defstate));
03438 return (generic_compare (u1->info->var->nullstate,
03439 u2->info->var->nullstate));
03440 case KDATATYPE:
03441 COMPARERETURN (ctype_compare (u1->info->datatype->type,
03442 u2->info->datatype->type));
03443 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
03444 u2->info->datatype->mut));
03445 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
03446 }
03447
03448 BADEXIT;
03449 }
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459 static void
03460 advanceField (char **s)
03461 {
03462 checkChar (s, '@');
03463 }
03464
03465 static void
03466 advanceName (char **s)
03467 {
03468 checkChar (s, '#');
03469 }
03470
03471 static vkind
03472 vkind_fromInt (int i)
03473 {
03474 if (i < VKFIRST || i > VKLAST)
03475 {
03476 llbuglit ("vkind_fromInt: out of range");
03477 }
03478
03479 return (vkind)i;
03480 }
03481
03482 static uentry
03483 uentry_makeConstantBase ( cstring name, ctype ct,
03484 typeIdSet access, nstate nullstate,
03485 fileloc loc, multiVal m)
03486 {
03487 uentry e = uentry_alloc ();
03488
03489 e->ukind = KCONST;
03490 e->uname = name;
03491 e->utype = ct;
03492 e->sref = sRef_makeConst (ct);
03493
03494 sRef_setNullState (e->sref, nullstate, loc);
03495 e->storageclass = SCNONE;
03496
03497 if (fileloc_isSpec (loc))
03498 {
03499 e->whereSpecified = loc;
03500 e->whereDeclared = fileloc_undefined;
03501 }
03502 else
03503 {
03504 e->whereSpecified = fileloc_undefined;
03505 e->whereDeclared = loc;
03506 }
03507
03508 e->whereDefined = fileloc_undefined;
03509 e->uses = filelocList_new ();
03510 e->isPrivate = FALSE;
03511 e->hasNameError = FALSE;
03512
03513 e->used = FALSE;
03514 e->lset = FALSE;
03515
03516 e->info = (uinfo) dmalloc (sizeof (*e->info));
03517 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
03518 e->info->uconst->val = m;
03519 e->info->uconst->access = access;
03520
03521 sRef_storeState (e->sref);
03522
03523 return (e);
03524 }
03525
03526 static uentry
03527 uentry_makeVariableBase ( cstring name, ctype ct, vkind kind,
03528 sstate defstate, nstate isnull, alkind aliased,
03529 exkind exp, chkind checked,
03530 fileloc loc)
03531 {
03532 uentry e = uentry_alloc ();
03533
03534 e->ukind = KVAR;
03535 e->uname = name;
03536 e->utype = ct;
03537 e->storageclass = SCNONE;
03538
03539 e->sref = sRef_makeType (ct);
03540 sRef_setNullState (e->sref, isnull, loc);
03541
03542 e->whereDefined = fileloc_undefined;
03543
03544 if (fileloc_isSpec (loc))
03545 {
03546 e->whereSpecified = loc;
03547 e->whereDeclared = fileloc_undefined;
03548 }
03549 else
03550 {
03551 e->whereSpecified = fileloc_undefined;
03552 e->whereDeclared = loc;
03553 }
03554
03555 e->isPrivate = FALSE;
03556 e->hasNameError = FALSE;
03557
03558 e->used = FALSE;
03559 e->lset = FALSE;
03560
03561 e->uses = filelocList_new ();
03562
03563 e->info = (uinfo) dmalloc (sizeof (*e->info));
03564 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
03565 e->info->var->kind = kind;
03566 e->info->var->checked = checked;
03567 e->info->var->defstate = defstate;
03568
03569 sRef_setDefState (e->sref, defstate, loc);
03570
03571 e->info->var->nullstate = sRef_getNullState (e->sref);
03572
03573 sRef_setExKind (e->sref, exp, loc);
03574 sRef_setAliasKind (e->sref, aliased, loc);
03575
03576 sRef_storeState (e->sref);
03577 return (e);
03578 }
03579
03580 static uentry
03581 uentry_makeDatatypeBase ( cstring name, ctype ct, ynm abs,
03582 ynm mut, ctype rtype, alkind ak, exkind exp,
03583 sstate defstate, nstate isnull,
03584 fileloc loc)
03585 {
03586 uentry e = uentry_alloc ();
03587
03588 e->ukind = KDATATYPE;
03589
03590 e->uname = name;
03591 e->utype = ct;
03592 e->storageclass = SCNONE;
03593 e->sref = sRef_makeUnknown ();
03594
03595
03596
03597
03598
03599 if (ctype_isUA (ct))
03600 {
03601 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
03602
03603 if (uentry_isValid (te))
03604 {
03605 sRef_setStateFromUentry (e->sref, te);
03606 }
03607 else
03608 {
03609
03610 }
03611 }
03612
03613 sRef_setAliasKind (e->sref, ak, loc);
03614 sRef_setExKind (e->sref, exp, loc);
03615
03616 sRef_setDefState (e->sref, defstate, loc);
03617
03618 if (ynm_isOn (abs) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
03619 {
03620 isnull = NS_ABSNULL;
03621 }
03622
03623 sRef_mergeNullState (e->sref, isnull);
03624
03625 e->whereDefined = fileloc_copy (loc);
03626
03627 if (fileloc_isSpec (loc))
03628 {
03629 e->whereSpecified = loc;
03630 e->whereDeclared = fileloc_undefined;
03631 }
03632 else
03633 {
03634 e->whereSpecified = fileloc_undefined;
03635 e->whereDeclared = loc;
03636 }
03637
03638 e->isPrivate = FALSE;
03639 e->hasNameError = FALSE;
03640
03641 e->used = FALSE;
03642 e->lset = FALSE;
03643 e->uses = filelocList_new ();
03644
03645 e->info = (uinfo) dmalloc (sizeof (*e->info));
03646 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
03647 e->info->datatype->abs = abs;
03648 e->info->datatype->mut = mut;
03649 e->info->datatype->type = rtype;
03650
03651 sRef_storeState (e->sref);
03652
03653 return (e);
03654 }
03655
03656 # ifndef NOLCL
03657 static void uentry_setHasGlobs (uentry ue)
03658 {
03659 llassert (uentry_isFunction (ue));
03660
03661 ue->info->fcn->hasGlobs = TRUE;
03662 }
03663
03664 static void uentry_setHasMods (uentry ue)
03665 {
03666 llassert (uentry_isFunction (ue));
03667
03668 ue->info->fcn->hasMods = TRUE;
03669 }
03670 # endif
03671
03672 bool uentry_hasGlobs (uentry ue)
03673 {
03674 if (uentry_isFunction (ue))
03675 {
03676 return (ue->info->fcn->hasGlobs);
03677 }
03678
03679 return FALSE;
03680 }
03681
03682 bool uentry_hasSpecialClauses (uentry ue)
03683 {
03684 return (uentry_isFunction (ue) && specialClauses_isDefined (ue->info->fcn->specclauses));
03685 }
03686
03687 specialClauses uentry_getSpecialClauses (uentry ue)
03688 {
03689 llassert (uentry_isFunction (ue));
03690 return ue->info->fcn->specclauses;
03691 }
03692
03693 bool uentry_hasMods (uentry ue)
03694 {
03695 if (uentry_isFunction (ue))
03696 {
03697 return (ue->info->fcn->hasMods);
03698 }
03699
03700 return FALSE;
03701 }
03702
03703 static uentry
03704 uentry_makeFunctionBase ( cstring name, ctype ct,
03705 typeIdSet access,
03706 bool hasGlobs, globSet globs,
03707 bool hasMods, sRefSet mods,
03708 alkind ak, exkind exp,
03709 sstate defstate, nstate isnull,
03710 exitkind exitCode,
03711 specCode sCode,
03712 qual nullPred,
03713 specialClauses specclauses,
03714 fileloc loc)
03715 {
03716 uentry e = uentry_alloc ();
03717 ctype ret;
03718
03719
03720 e->ukind = KFCN;
03721 e->uname = name;
03722 e->utype = ct;
03723 e->storageclass = SCNONE;
03724
03725 if (ctype_isFunction (ct))
03726 {
03727 ret = ctype_returnValue (ct);
03728 }
03729 else
03730 {
03731 if (ctype_isKnown (ct))
03732 {
03733 llbug (message ("not function: %s", ctype_unparse (ct)));
03734 }
03735
03736 ret = ctype_unknown;
03737 }
03738
03739 e->sref = sRef_makeType (ret);
03740
03741 if (ctype_isUA (ret))
03742 {
03743 sRef_setStateFromType (e->sref, ret);
03744 }
03745
03746 sRef_setDefined (e->sref, loc);
03747 sRef_setNullState (e->sref, isnull, loc);
03748
03749 sRef_setAliasKind (e->sref, ak, loc);
03750 sRef_setExKind (e->sref, exp, loc);
03751 sRef_setDefState (e->sref, defstate, loc);
03752
03753 e->whereSpecified = loc;
03754 e->whereDefined = fileloc_undefined;
03755
03756 e->isPrivate = FALSE;
03757 e->hasNameError = FALSE;
03758
03759 e->used = FALSE;
03760 e->lset = FALSE;
03761 e->uses = filelocList_new ();
03762
03763 e->info = (uinfo) dmalloc (sizeof (*e->info));
03764 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
03765
03766 e->info->fcn->exitCode = exitCode;
03767 e->info->fcn->specialCode = sCode;
03768 e->info->fcn->nullPred = nullPred;
03769 e->info->fcn->access = access;
03770
03771 e->info->fcn->specclauses = specclauses;
03772 e->info->fcn->hasGlobs = hasGlobs;
03773 e->info->fcn->globs = globs;
03774
03775 e->info->fcn->hasMods = hasMods;
03776 e->info->fcn->mods = mods;
03777
03778 e->info->fcn->defparams = uentryList_undefined;
03779 e->whereDeclared = fileloc_undefined;
03780
03781 sRef_storeState (e->sref);
03782
03783 return (e);
03784 }
03785
03786 static uentry
03787 uentry_makeTagBase ( cstring name, ekind tagkind,
03788 ctype ct, ctype rtype, fileloc loc)
03789 {
03790 uentry e = uentry_alloc ();
03791
03792 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
03793 {
03794 llbuglit ("uentry_makeTagBase: not a tag type");
03795 }
03796
03797
03798 e->ukind = tagkind;
03799 e->uname = name;
03800 e->utype = ct;
03801 e->sref = sRef_makeUnknown ();
03802 e->storageclass = SCNONE;
03803
03804 if (fileloc_isSpec (loc))
03805 {
03806 e->whereSpecified = loc;
03807 e->whereDeclared = fileloc_undefined;
03808 }
03809 else
03810 {
03811 e->whereDeclared = loc;
03812 e->whereSpecified = fileloc_undefined;
03813 }
03814
03815 e->whereDefined = fileloc_undefined;
03816
03817 e->isPrivate = FALSE;
03818 e->hasNameError = FALSE;
03819
03820 e->used = FALSE;
03821 e->lset = FALSE;
03822 e->uses = filelocList_new ();
03823
03824 e->info = (uinfo) dmalloc (sizeof (*e->info));
03825 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
03826 e->info->datatype->abs = NO;
03827 e->info->datatype->mut = MAYBE;
03828 e->info->datatype->type = rtype;
03829
03830 sRef_storeState (e->sref);
03831
03832 return (e);
03833 }
03834
03835 static uentry
03836 uentry_makeIterBase ( cstring name, typeIdSet access,
03837 ctype ct, fileloc loc)
03838 {
03839 uentry e = uentry_alloc ();
03840
03841
03842 e->ukind = KITER;
03843 e->uname = name;
03844 e->utype = ct;
03845 e->sref = sRef_makeUnknown ();
03846 e->storageclass = SCNONE;
03847
03848 if (fileloc_isSpec (loc))
03849 {
03850 e->whereSpecified = loc;
03851 e->whereDeclared = fileloc_undefined;
03852 }
03853 else
03854 {
03855 e->whereDeclared = loc;
03856 e->whereSpecified = fileloc_undefined;
03857 }
03858
03859 e->whereDefined = fileloc_undefined;
03860
03861 e->isPrivate = FALSE;
03862 e->hasNameError = FALSE;
03863
03864 e->used = FALSE;
03865 e->lset = FALSE;
03866 e->uses = filelocList_new ();
03867
03868 e->info = (uinfo) dmalloc (sizeof (*e->info));
03869 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
03870 e->info->iter->access = access;
03871 e->info->iter->mods = sRefSet_undefined;
03872 e->info->iter->globs = globSet_undefined;
03873
03874 sRef_storeState (e->sref);
03875 return (e);
03876 }
03877
03878 static uentry
03879 uentry_makeEndIterBase ( cstring name, typeIdSet access,
03880 fileloc loc)
03881 {
03882 uentry e = uentry_alloc ();
03883
03884
03885 e->ukind = KENDITER;
03886 e->storageclass = SCNONE;
03887 e->uname = name;
03888 e->utype = ctype_unknown;
03889 e->sref = sRef_makeUnknown ();
03890
03891 if (fileloc_isSpec (loc))
03892 {
03893 e->whereSpecified = loc;
03894 e->whereDeclared = fileloc_undefined;
03895 }
03896 else
03897 {
03898 e->whereDeclared = loc;
03899 e->whereSpecified = fileloc_undefined;
03900 }
03901
03902 e->whereDefined = fileloc_undefined;
03903
03904 e->isPrivate = FALSE;
03905 e->hasNameError = FALSE;
03906
03907 e->used = FALSE;
03908 e->lset = FALSE;
03909 e->uses = filelocList_new ();
03910
03911 e->info = (uinfo) dmalloc (sizeof (*e->info));
03912 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
03913 e->info->enditer->access = access;
03914 sRef_storeState (e->sref);
03915
03916 return (e);
03917 }
03918
03919 void uentry_markFree ( uentry u)
03920 {
03921
03922
03923 }
03924
03925
03926 uentry
03927 uentry_undump (ekind kind, fileloc loc, char **s)
03928 {
03929 uentry ue;
03930
03931 if (**s == '!')
03932 {
03933 checkChar (s, '!');
03934 checkChar (s, '.');
03935 ue = uentry_makeElipsisMarker ();
03936 }
03937 else
03938 {
03939 ctype ct = ctype_undump (s);
03940 cstring name;
03941
03942 switch (kind)
03943 {
03944 case KVAR:
03945 {
03946 vkind tkind;
03947 sstate defstate;
03948 nstate isnull;
03949 alkind aliased;
03950 exkind exp;
03951 chkind checked;
03952
03953 checkChar (s, '|');
03954
03955 if (optCheckChar (s, '@'))
03956 {
03957 tkind = vkind_fromInt (getInt (s));
03958 checkChar (s, '|');
03959 }
03960 else
03961 {
03962 tkind = VKPARAM;
03963 }
03964
03965 if (optCheckChar (s, '$'))
03966 {
03967 defstate = SS_UNKNOWN;
03968 isnull = NS_UNKNOWN;
03969 aliased = AK_IMPTEMP;
03970 exp = XO_UNKNOWN;
03971 checked = CH_UNKNOWN;
03972 }
03973 else if (optCheckChar (s, '&'))
03974 {
03975 defstate = SS_DEFINED;
03976 isnull = NS_UNKNOWN;
03977 aliased = AK_IMPTEMP;
03978 exp = XO_UNKNOWN;
03979 checked = CH_UNKNOWN;
03980 }
03981 else if (optCheckChar (s, '^'))
03982 {
03983 defstate = SS_UNKNOWN;
03984 isnull = NS_UNKNOWN;
03985 aliased = AK_IMPTEMP;
03986 exp = XO_UNKNOWN;
03987 checked = CH_UNKNOWN;
03988 }
03989 else
03990 {
03991 defstate = sstate_fromInt (getInt (s));
03992 advanceField (s); isnull = nstate_fromInt (getInt (s));
03993 advanceField (s); aliased = alkind_fromInt (getInt (s));
03994
03995 if (optCheckChar (s, '&'))
03996 {
03997 exp = XO_UNKNOWN;
03998 checked = CH_UNKNOWN;
03999 }
04000 else
04001 {
04002 advanceField (s); exp = exkind_fromInt (getInt (s));
04003 advanceField (s); checked = (chkind) (getInt (s));
04004 }
04005 }
04006
04007 advanceName (s);
04008 name = getStringWord (s);
04009
04010 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
04011 isnull, aliased, exp,
04012 checked, fileloc_copy (loc));
04013 }
04014 break;
04015 case KDATATYPE:
04016 {
04017 ynm abs;
04018 ynm mut;
04019 ctype rtype;
04020 sstate defstate;
04021 nstate isnull;
04022 alkind aliased;
04023 exkind exp;
04024
04025 advanceField (s); abs = ynm_fromCodeChar (loadChar (s));
04026 advanceField (s); mut = ynm_fromCodeChar (loadChar (s));
04027 advanceField (s); defstate = sstate_fromInt (getInt (s));
04028 advanceField (s); isnull = nstate_fromInt (getInt (s));
04029 advanceField (s); aliased = alkind_fromInt (getInt (s));
04030 advanceField (s); exp = exkind_fromInt (getInt (s));
04031 advanceField (s); rtype = ctype_undump (s);
04032 advanceName (s);
04033 name = getStringWord (s);
04034
04035 ue = uentry_makeDatatypeBase (name, ct, abs, mut, rtype,
04036 aliased, exp, defstate, isnull,
04037 fileloc_copy (loc));
04038 }
04039 break;
04040 case KFCN:
04041 {
04042 alkind ak;
04043 exkind exp;
04044 sstate defstate;
04045 nstate isnull;
04046 exitkind exitCode;
04047 specCode specc;
04048 qual nullPred;
04049 typeIdSet access;
04050 bool hasGlobs;
04051 globSet globs;
04052 bool hasMods;
04053 sRefSet mods;
04054 specialClauses specclauses;
04055
04056 if (optCheckChar (s, '$'))
04057 {
04058 defstate = SS_DEFINED;
04059 isnull = NS_UNKNOWN;
04060 exitCode = XK_UNKNOWN;
04061 specc = SPC_NONE;
04062 nullPred = QU_UNKNOWN;
04063 }
04064 else
04065 {
04066 advanceField (s); defstate = sstate_fromInt (getInt (s));
04067 advanceField (s); isnull = nstate_fromInt (getInt (s));
04068 advanceField (s); exitCode = exitkind_fromInt (getInt (s));
04069 advanceField (s); specc = specCode_fromInt (getInt (s));
04070 advanceField (s); nullPred = qual_fromInt (getInt (s));
04071 }
04072
04073 if (optCheckChar (s, '$'))
04074 {
04075 hasGlobs = FALSE;
04076 globs = globSet_undefined;
04077 hasMods = FALSE;
04078 mods = sRefSet_undefined;
04079 }
04080 else if (optCheckChar (s, '^'))
04081 {
04082 hasGlobs = TRUE;
04083 globs = globSet_undefined;
04084 hasMods = TRUE;
04085 mods = sRefSet_undefined;
04086 }
04087 else
04088 {
04089 advanceField (s); hasGlobs = bool_fromInt (getInt (s));
04090 advanceField (s); globs = globSet_undump (s);
04091 advanceField (s); hasMods = bool_fromInt (getInt (s));
04092 advanceField (s); mods = sRefSet_undump (s);
04093 }
04094
04095 if (optCheckChar (s, '$'))
04096 {
04097 ak = AK_UNKNOWN;
04098 exp = XO_UNKNOWN;
04099 }
04100 else
04101 {
04102 advanceField (s); ak = alkind_fromInt (getInt (s));
04103 advanceField (s); exp = exkind_fromInt (getInt (s));
04104 }
04105
04106 advanceField (s); access = typeIdSet_undump (s);
04107
04108 if (optCheckChar (s, '@'))
04109 {
04110 specclauses = specialClauses_undump (s);
04111 }
04112 else
04113 {
04114 specclauses = specialClauses_undefined;
04115 }
04116
04117 advanceName (s); name = getStringWord (s);
04118
04119 ue = uentry_makeFunctionBase (name, ct, access,
04120 hasGlobs, globs,
04121 hasMods, mods,
04122 ak, exp, defstate, isnull,
04123 exitCode, specc, nullPred,
04124 specclauses,
04125 fileloc_copy (loc));
04126 DPRINTF (("Undump: %s", uentry_unparse (ue)));
04127 }
04128 break;
04129 case KITER:
04130 {
04131 typeIdSet access;
04132
04133 advanceField (s); access = typeIdSet_undump (s);
04134 advanceName (s); name = getStringWord (s);
04135
04136 ue = uentry_makeIterBase (name, access, ct,
04137 fileloc_copy (loc));
04138 }
04139 break;
04140 case KENDITER:
04141 {
04142 typeIdSet access;
04143
04144 advanceField (s); access = typeIdSet_undump (s);
04145 advanceName (s); name = getStringWord (s);
04146
04147 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
04148 }
04149 break;
04150 case KENUMCONST:
04151 case KCONST:
04152 {
04153 typeIdSet access;
04154 multiVal val;
04155 nstate nullstate;
04156
04157 if (optCheckChar (s, '$'))
04158 {
04159 val = multiVal_undefined;
04160 access = typeIdSet_undefined;
04161 nullstate = NS_UNKNOWN;
04162 }
04163 else
04164 {
04165 advanceField (s); val = multiVal_undump (s);
04166 advanceField (s); access = typeIdSet_undump (s);
04167 advanceField (s); nullstate = nstate_fromInt (getInt (s));
04168 }
04169
04170 advanceName (s); name = getStringWord (s);
04171
04172 ue = uentry_makeConstantBase (name, ct, access,
04173 nullstate, fileloc_copy (loc), val);
04174 break;
04175 }
04176 case KSTRUCTTAG:
04177 case KUNIONTAG:
04178 case KENUMTAG:
04179 {
04180 ctype rtype;
04181
04182 advanceField (s); rtype = ctype_undump (s);
04183 advanceName (s); name = getStringWord (s);
04184 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
04185 }
04186 break;
04187 case KINVALID:
04188 llcontbuglit ("uentry_undump: invalid");
04189 ue = uentry_undefined;
04190 break;
04191 case KELIPSMARKER:
04192 llcontbuglit ("uentry_undump: elips marker");
04193 ue = uentry_undefined;
04194 break;
04195 }
04196 }
04197
04198 return (ue);
04199 }
04200
04201 cstring
04202 uentry_dump (uentry v)
04203 {
04204 return (uentry_dumpAux (v, FALSE));
04205 }
04206
04207 cstring
04208 uentry_dumpParam (uentry v)
04209 {
04210 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
04211 ("dump: %s", uentry_unparseFull (v)));
04212
04213 return (uentry_dumpAux (v, TRUE));
04214 }
04215
04216 static cstring
04217 uentry_dumpAux (uentry v, bool isParam)
04218 {
04219 llassert (uentry_isValid (v));
04220
04221 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
04222
04223 switch (v->ukind)
04224 {
04225 case KINVALID:
04226 llcontbuglit ("uentry_dump: invalid entry");
04227 return cstring_undefined;
04228 case KELIPSMARKER:
04229 return (message ("!."));
04230 case KVAR:
04231 {
04232 cstring sdump;
04233 vkind vk = v->info->var->kind;
04234 sstate dss = sRef_getDefState (v->sref);
04235 nstate nst = sRef_getNullState (v->sref);
04236 alkind alk = sRef_getAliasKind (v->sref);
04237 exkind exk = sRef_getExKind (v->sref);
04238 chkind chk = v->info->var->checked;
04239
04240 DPRINTF (("Dumping var"));
04241
04242 if (dss == SS_UNKNOWN
04243 && nst == NS_UNKNOWN
04244 && alk == AK_IMPTEMP
04245 && exk == XO_UNKNOWN
04246 && chk == CH_UNKNOWN)
04247 {
04248 sdump = cstring_makeLiteral ("$");
04249 }
04250 else if (dss == SS_DEFINED
04251 && nst == NS_UNKNOWN
04252 && alk == AK_IMPTEMP
04253 && exk == XO_UNKNOWN
04254 && chk == CH_UNKNOWN)
04255 {
04256 sdump = cstring_makeLiteral ("&");
04257 }
04258 else if (dss == SS_UNKNOWN
04259 && nst == NS_UNKNOWN
04260 && alk == AK_UNKNOWN
04261 && exk == XO_UNKNOWN
04262 && chk == CH_UNKNOWN)
04263 {
04264 sdump = cstring_makeLiteral ("^");
04265 }
04266 else if (exk == XO_UNKNOWN
04267 && chk == CH_UNKNOWN)
04268 {
04269 sdump = message ("%d@%d@%d&",
04270 (int) dss,
04271 (int) nst,
04272 (int) alk);
04273 }
04274 else
04275 {
04276 sdump = message ("%d@%d@%d@%d@%d",
04277 (int) dss,
04278 (int) nst,
04279 (int) alk,
04280 (int) exk,
04281 (int) chk);
04282 }
04283
04284
04285 if (vk != VKPARAM)
04286 {
04287 return (message ("%q|@%d|%q#%s",
04288 ctype_dump (v->utype),
04289 (int) vk,
04290 sdump,
04291 isParam ? cstring_undefined : v->uname));
04292 }
04293 else
04294 {
04295 return (message ("%q|%q#%s",
04296 ctype_dump (v->utype),
04297 sdump,
04298 isParam ? cstring_undefined : v->uname));
04299 }
04300
04301 }
04302 case KDATATYPE:
04303 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
04304 ctype_dump (v->utype),
04305 ynm_unparseCode (v->info->datatype->abs),
04306 ynm_unparseCode (v->info->datatype->mut),
04307 (int) sRef_getDefState (v->sref),
04308 (int) sRef_getNullState (v->sref),
04309 (int) sRef_getAliasKind (v->sref),
04310 (int) sRef_getExKind (v->sref),
04311 ctype_dump (v->info->datatype->type),
04312 v->uname));
04313 case KFCN:
04314 {
04315 cstring sdump, gdump, adump;
04316 alkind alk = sRef_getAliasKind (v->sref);
04317 exkind exk = sRef_getExKind (v->sref);
04318
04319 if (sRef_getDefState (v->sref) == SS_DEFINED
04320 && !nstate_isKnown (sRef_getNullState (v->sref))
04321 && !exitkind_isKnown (v->info->fcn->exitCode)
04322 && v->info->fcn->specialCode == SPC_NONE
04323 && v->info->fcn->nullPred == QU_UNKNOWN)
04324 {
04325 sdump = cstring_makeLiteral ("$");
04326 }
04327 else
04328 {
04329 sdump = message ("@%d@%d@%d@%d@%d",
04330 (int) sRef_getDefState (v->sref),
04331 (int) sRef_getNullState (v->sref),
04332 (int) v->info->fcn->exitCode,
04333 (int) v->info->fcn->specialCode,
04334 (int) v->info->fcn->nullPred);
04335 }
04336
04337 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
04338 {
04339 gdump = cstring_makeLiteral ("$");
04340 }
04341 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
04342 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
04343 {
04344 gdump = cstring_makeLiteral ("^");
04345 }
04346 else
04347 {
04348 gdump = message ("@%s@%q@%s@%q",
04349 bool_dump (uentry_hasGlobs (v)),
04350 globSet_dump (uentry_getGlobs (v)),
04351 bool_dump (uentry_hasMods (v)),
04352 sRefSet_dump (uentry_getMods (v)));
04353 }
04354
04355 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
04356 {
04357 adump = cstring_makeLiteral ("$");
04358 }
04359 else
04360 {
04361 adump = message ("@%d@%d", (int) alk, (int) exk);
04362 }
04363
04364 if (uentry_hasSpecialClauses (v))
04365 {
04366 return (message ("%q%q%q%q@%q@%q#%s",
04367 ctype_dump (v->utype),
04368 sdump,
04369 gdump,
04370 adump,
04371 typeIdSet_dump (uentry_accessType (v)),
04372 specialClauses_dump (v->info->fcn->specclauses),
04373 v->uname));
04374 }
04375 else
04376 {
04377 return (message ("%q%q%q%q@%q#%s",
04378 ctype_dump (v->utype),
04379 sdump,
04380 gdump,
04381 adump,
04382 typeIdSet_dump (uentry_accessType (v)),
04383 v->uname));
04384 }
04385 }
04386 case KITER:
04387 return (message ("%q@%q#%s",
04388 ctype_dump (v->utype),
04389 typeIdSet_dump (v->info->iter->access),
04390 v->uname));
04391 case KENDITER:
04392 return (message ("%q@%q#%s",
04393 ctype_dump (v->utype),
04394 typeIdSet_dump (uentry_accessType (v)),
04395 v->uname));
04396 case KENUMCONST:
04397 case KCONST:
04398 {
04399 cstring sdump;
04400
04401 if (multiVal_isUnknown (v->info->uconst->val)
04402 && typeIdSet_isEmpty (uentry_accessType (v))
04403 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
04404 {
04405 sdump = cstring_makeLiteral ("$");
04406 }
04407 else
04408 {
04409 sdump = message ("@%q@%q@%d",
04410 multiVal_dump (v->info->uconst->val),
04411 typeIdSet_dump (uentry_accessType (v)),
04412 (int) sRef_getNullState (v->sref));
04413 }
04414
04415 return (message ("%q%q#%s",
04416 ctype_dump (v->utype),
04417 sdump,
04418 v->uname));
04419 }
04420 case KSTRUCTTAG:
04421 case KUNIONTAG:
04422 case KENUMTAG:
04423 return (message ("%q@%q#%s",
04424 ctype_dump (v->utype),
04425 ctype_dump (v->info->datatype->type), v->uname));
04426 }
04427
04428 BADEXIT;
04429 }
04430
04431 cstring
04432 uentry_unparseAbbrev (uentry v)
04433 {
04434 if (!uentry_isVariable (v))
04435 {
04436 llcontbuglit ("uentry_unparseAbbrev: not variable");
04437 return uentry_unparse (v);
04438 }
04439
04440 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
04441 }
04442
04443 cstring
04444 uentry_unparse (uentry v)
04445 {
04446 cstring st;
04447
04448 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
04449 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
04450
04451 st = uentry_getName (v);
04452
04453 if (cstring_isDefined (st))
04454 {
04455 return (ctype_unparseDeclaration (v->utype, st));
04456 }
04457 else
04458 {
04459 cstring_free (st);
04460 return (cstring_copy (ctype_unparse (v->utype)));
04461 }
04462 }
04463
04464 cstring
04465 uentry_unparseFull (uentry v)
04466 {
04467 if (uentry_isUndefined (v))
04468 {
04469 return (cstring_makeLiteral ("<undefined>"));
04470 }
04471 else if (uentry_isDatatype (v))
04472 {
04473 return (message ("[%d] [%s] %s %q : %t [%t] %s %s // %q [s: %q; d: %q]",
04474 (int) v,
04475 ekind_unparse (v->ukind),
04476 v->uname,
04477 uentry_getName (v),
04478 v->utype,
04479 ctype_isDefined (v->info->datatype->type)
04480 ? v->info->datatype->type : ctype_unknown,
04481 ynm_unparse (v->info->datatype->mut),
04482 ynm_unparse (v->info->datatype->abs),
04483 sRef_unparseState (v->sref),
04484 fileloc_unparse (v->whereSpecified),
04485 fileloc_unparse (v->whereDefined)));
04486 }
04487 else if (uentry_isFunction (v))
04488 {
04489 return (message ("[%w] = [%s] %q : %t / sref: %q / mods: %q / "
04490 "globs: %q / [s: %q; decl: %q; def: %q]",
04491 (long unsigned) v,
04492 ekind_unparse (v->ukind),
04493 uentry_getName (v),
04494 v->utype,
04495 sRef_unparseFull (v->sref),
04496 sRefSet_unparse (v->info->fcn->mods),
04497 globSet_unparse (v->info->fcn->globs),
04498 fileloc_unparse (v->whereSpecified),
04499 fileloc_unparse (v->whereDeclared),
04500 fileloc_unparse (v->whereDefined)));
04501 }
04502 else if (uentry_isIter (v))
04503 {
04504 return (message ("[%s] %q: %t / %q [s: %q; d: %q]",
04505 ekind_unparse (v->ukind),
04506 uentry_getName (v),
04507 v->utype,
04508 sRef_unparseFull (v->sref),
04509 fileloc_unparse (v->whereSpecified),
04510 fileloc_unparse (v->whereDefined)));
04511 }
04512 else if (uentry_isVariable (v))
04513 {
04514 return
04515 (message ("[check: %s] / [%w] = [%s] %s : %t %q [s: %q; def: %q; dec: %q] "
04516 "kind <%d> isout <%d> used <%d>",
04517 checkedName (v->info->var->checked),
04518 (long unsigned) v,
04519 ekind_unparse (v->ukind),
04520 v->uname,
04521 v->utype,
04522 sRef_unparseDeep (v->sref),
04523 fileloc_unparse (v->whereSpecified),
04524 fileloc_unparse (v->whereDefined),
04525 fileloc_unparse (v->whereDeclared),
04526 (int) v->info->var->kind,
04527 (int) v->info->var->defstate,
04528 (int) v->used));
04529 }
04530 else
04531 {
04532 return (message ("[%s] %s : %t %q at [s: %q; d: %q]",
04533 ekind_unparse (v->ukind),
04534 v->uname,
04535 v->utype,
04536 sRef_unparseFull (v->sref),
04537 fileloc_unparse (v->whereSpecified),
04538 fileloc_unparse (v->whereDefined)));
04539
04540 }
04541 }
04542
04543 bool uentry_hasAccessType (uentry e)
04544 {
04545 if (uentry_isValid (e))
04546 {
04547 switch (e->ukind)
04548 {
04549 case KITER:
04550 return (!typeIdSet_isEmpty (e->info->iter->access));
04551 case KENDITER:
04552 return (!typeIdSet_isEmpty (e->info->enditer->access));
04553 case KFCN:
04554 return (!typeIdSet_isEmpty (e->info->fcn->access));
04555 case KENUMCONST:
04556 case KCONST:
04557 return (!typeIdSet_isEmpty (e->info->uconst->access));
04558 default:
04559 return FALSE;
04560 }
04561 }
04562
04563 return FALSE;
04564 }
04565
04566 typeIdSet uentry_accessType (uentry e)
04567 {
04568 if (uentry_isValid (e))
04569 {
04570 switch (e->ukind)
04571 {
04572 case KITER:
04573 return (e->info->iter->access);
04574 case KENDITER:
04575 return (e->info->enditer->access);
04576 case KFCN:
04577 return (e->info->fcn->access);
04578 case KENUMCONST:
04579 case KCONST:
04580 return (e->info->uconst->access);
04581 default:
04582 break;
04583 }
04584 }
04585
04586 return typeIdSet_undefined;
04587 }
04588
04589 bool
04590 uentry_isVariable (uentry e)
04591 {
04592 return (uentry_isVar (e));
04593 }
04594
04595 bool
04596 uentry_isSpecified (uentry e)
04597 {
04598 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
04599 }
04600
04601 static bool
04602 uentry_isReallySpecified (uentry e)
04603 {
04604 return (uentry_isValid (e)
04605 && fileloc_isRealSpec (e->whereSpecified));
04606 }
04607
04608 bool
04609 uentry_isVar (uentry e)
04610 {
04611 return (!uentry_isUndefined (e) && e->ukind == KVAR);
04612 }
04613
04614 bool
04615 uentry_isFakeTag (uentry e)
04616 {
04617 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
04618 }
04619
04620 bool
04621 uentry_isDatatype (uentry e)
04622 {
04623 return (!uentry_isUndefined (e) &&
04624 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
04625 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
04626 }
04627
04628 void
04629 uentry_setAbstract (uentry e)
04630 {
04631 typeId oldid;
04632
04633 llassert (uentry_isDatatype (e)
04634 && (ynm_isMaybe (e->info->datatype->abs)));
04635
04636 oldid = ctype_typeId (e->info->datatype->type);
04637 e->info->datatype->abs = YES;
04638 e->info->datatype->type = ctype_createAbstract (oldid);
04639 }
04640
04641 void
04642 uentry_setConcrete (uentry e)
04643 {
04644 llassert (uentry_isDatatype (e)
04645 && (ynm_isMaybe (e->info->datatype->abs)));
04646
04647 e->info->datatype->abs = NO;
04648 }
04649
04650 bool
04651 uentry_isAbstractDatatype (uentry e)
04652 {
04653 return (uentry_isDatatype (e)
04654 && (ynm_isOn (e->info->datatype->abs)));
04655 }
04656
04657 bool
04658 uentry_isMaybeAbstract (uentry e)
04659 {
04660 return (uentry_isDatatype (e)
04661 && (ynm_isMaybe (e->info->datatype->abs)));
04662 }
04663
04664 bool
04665 uentry_isMutableDatatype (uentry e)
04666 {
04667 bool res = uentry_isDatatype (e)
04668 && (ynm_toBoolRelaxed (e->info->datatype->mut));
04669
04670 return res;
04671 }
04672
04673 bool
04674 uentry_isRefCountedDatatype (uentry e)
04675 {
04676 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
04677 }
04678
04679 bool
04680 uentry_isParam (uentry u)
04681 {
04682 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
04683 || u->info->var->kind == VKYIELDPARAM));
04684 }
04685
04686 bool
04687 uentry_isExpandedMacro (uentry u)
04688 {
04689 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
04690 }
04691
04692 bool
04693 uentry_isSefParam (uentry u)
04694 {
04695 return (uentry_isVariable (u)
04696 && (u->info->var->kind == VKSEFPARAM
04697 || u->info->var->kind == VKREFSEFPARAM
04698 || u->info->var->kind == VKSEFRETPARAM
04699 || u->info->var->kind == VKREFSEFRETPARAM));
04700 }
04701
04702 bool
04703 uentry_isRefParam (uentry u)
04704 {
04705 return (uentry_isVariable (u)
04706 && (u->info->var->kind == VKREFPARAM
04707 || u->info->var->kind == VKREFYIELDPARAM
04708 || u->info->var->kind == VKREFSEFPARAM
04709 || u->info->var->kind == VKREFSEFRETPARAM));
04710 }
04711
04712 bool
04713 uentry_isAnyParam (uentry u)
04714 {
04715 return (uentry_isVariable (u)
04716 && ((u->info->var->kind == VKPARAM)
04717 || (u->info->var->kind == VKSEFPARAM)
04718 || (u->info->var->kind == VKYIELDPARAM)
04719 || (u->info->var->kind == VKRETPARAM)
04720 || (u->info->var->kind == VKSEFRETPARAM)));
04721 }
04722
04723 sstate
04724 uentry_getDefState (uentry u)
04725 {
04726 if (uentry_isValid (u))
04727 {
04728 return (sRef_getDefState (u->sref));
04729 }
04730 else
04731 {
04732 return (SS_UNKNOWN);
04733 }
04734 }
04735
04736 bool
04737 uentry_isOut (uentry u)
04738 {
04739 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
04740 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
04741 }
04742
04743 bool
04744 uentry_isPartial (uentry u)
04745 {
04746 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
04747 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
04748 }
04749
04750 bool
04751 uentry_isStateSpecial (uentry u)
04752 {
04753 return ((uentry_isVariable (u)
04754 && (u->info->var->defstate == SS_SPECIAL))
04755 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
04756 }
04757
04758 exitkind uentry_getExitCode (uentry ue)
04759 {
04760 if (uentry_isFunction (ue))
04761 {
04762 return ue->info->fcn->exitCode;
04763 }
04764 else
04765 {
04766 return XK_UNKNOWN;
04767 }
04768 }
04769
04770 qual
04771 uentry_nullPred (uentry u)
04772 {
04773 llassert (uentry_isRealFunction (u));
04774
04775 if (uentry_isFunction (u))
04776 {
04777 return (u->info->fcn->nullPred);
04778 }
04779 else
04780 {
04781 return QU_UNKNOWN;
04782 }
04783 }
04784
04785 bool
04786 uentry_possiblyNull (uentry u)
04787 {
04788 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
04789 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
04790 }
04791
04792 alkind
04793 uentry_getAliasKind (uentry u)
04794 {
04795 if (uentry_isValid (u))
04796 {
04797 return (sRef_getAliasKind (uentry_getSref (u)));
04798 }
04799 else
04800 {
04801 return AK_UNKNOWN;
04802 }
04803 }
04804
04805 exkind
04806 uentry_getExpKind (uentry u)
04807 {
04808 if (uentry_isValid (u))
04809 {
04810 return (sRef_getExKind (uentry_getSref (u)));
04811 }
04812 else
04813 {
04814 return XO_UNKNOWN;
04815 }
04816 }
04817
04818 bool
04819 uentry_isIter (uentry e)
04820 {
04821 return (!uentry_isUndefined (e) && e->ukind == KITER);
04822 }
04823
04824 bool
04825 uentry_isEndIter (uentry e)
04826 {
04827 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
04828 }
04829
04830 bool
04831 uentry_isRealFunction (uentry e)
04832 {
04833 return (uentry_isFunction (e) ||
04834 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
04835 }
04836
04837 bool
04838 uentry_hasName (uentry e)
04839 {
04840 if (uentry_isValid (e))
04841 {
04842 cstring s = e->uname;
04843
04844 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")));
04845 }
04846 else
04847 {
04848 return FALSE;
04849 }
04850 }
04851
04852 bool uentry_hasRealName (uentry e)
04853 {
04854 return (uentry_isValid (e) && cstring_isNonEmpty (e->uname));
04855 }
04856
04857
04858 globSet
04859 uentry_getGlobs (uentry l)
04860 {
04861 if (uentry_isInvalid (l))
04862 {
04863 return globSet_undefined;
04864 }
04865
04866 if (l->ukind != KFCN)
04867 {
04868 if (l->ukind != KITER && l->ukind != KENDITER)
04869 {
04870 if (l->ukind == KVAR)
04871 {
04872 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
04873 uentry_unparse (l),
04874 ekind_unparse (l->ukind)));
04875 }
04876 else
04877 {
04878 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
04879 uentry_unparse (l),
04880 ekind_unparse (l->ukind)));
04881 }
04882 }
04883 return globSet_undefined;
04884 }
04885
04886 return l->info->fcn->globs;
04887 }
04888
04889 sRefSet
04890 uentry_getMods (uentry l)
04891 {
04892 llassert (uentry_isValid (l));
04893
04894 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
04895 {
04896 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
04897 return sRefSet_undefined;
04898 }
04899
04900 return l->info->fcn->mods;
04901 }
04902
04903 ekind
04904 uentry_getKind (uentry e)
04905 {
04906 llassert (uentry_isValid (e));
04907
04908 return (e->ukind);
04909 }
04910
04911 multiVal uentry_getConstantValue (uentry e)
04912 {
04913 llassert (uentry_isEitherConstant (e));
04914
04915 return (e->info->uconst->val);
04916 }
04917
04918 uentryList
04919 uentry_getParams (uentry l)
04920 {
04921 if (uentry_isInvalid (l)) return uentryList_undefined;
04922
04923 switch (l->ukind)
04924 {
04925 case KFCN:
04926 case KITER:
04927 {
04928 ctype ct = l->utype;
04929
04930 if (ctype_isFunction (ct))
04931 {
04932 return (ctype_argsFunction (ct));
04933 }
04934 else
04935 {
04936 return uentryList_undefined;
04937 }
04938 }
04939 case KVAR:
04940 {
04941 ctype ct = l->utype;
04942
04943 llassert (ctype_isFunction (ct));
04944 return (ctype_argsFunction (ct));
04945 }
04946 BADDEFAULT;
04947 }
04948 BADEXIT;
04949 }
04950
04951 cstring
04952 uentry_rawName (uentry e)
04953 {
04954 if (uentry_isValid (e))
04955 {
04956 return (e->uname);
04957 }
04958 else
04959 {
04960 return cstring_undefined;
04961 }
04962 }
04963
04964 static cstring
04965 uentry_getOptName (uentry e)
04966 {
04967 cstring s = uentry_getName (e);
04968
04969 if (cstring_isDefined (s))
04970 {
04971 s = cstring_appendChar (s, ' ');
04972 }
04973
04974 return s;
04975 }
04976
04977 cstring
04978 uentry_getName (uentry e)
04979 {
04980 cstring ret = cstring_undefined;
04981
04982 if (uentry_isValid (e))
04983 {
04984
04985 if (uentry_isAnyTag (e))
04986 {
04987 ret = fixTagName (e->uname);
04988 }
04989 else if (uentry_isAnyParam (e))
04990 {
04991 ret = cstring_copy (fixParamName (e->uname));
04992 }
04993 else
04994 {
04995 ret = cstring_copy (e->uname);
04996 }
04997 }
04998
04999 return ret;
05000 }
05001
05002 cstring uentry_getRealName (uentry e)
05003 {
05004 if (uentry_isValid (e))
05005 {
05006 if (uentry_isAnyTag (e))
05007 {
05008 return (cstring_undefined);
05009 }
05010 else
05011 {
05012 return (e->uname);
05013 }
05014 }
05015 return cstring_undefined;
05016 }
05017
05018 ctype uentry_getType (uentry e)
05019 {
05020 if (uentry_isValid (e))
05021 {
05022 return e->utype;
05023 }
05024 else
05025 {
05026 return ctype_unknown;
05027 }
05028 }
05029
05030 fileloc uentry_whereLast (uentry e)
05031 {
05032 fileloc loc;
05033
05034 if (uentry_isInvalid (e))
05035 {
05036 return fileloc_undefined;
05037 }
05038
05039 loc = e->whereDefined;
05040
05041 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
05042 {
05043 return loc;
05044 }
05045
05046 loc = uentry_whereDeclared (e);
05047
05048 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
05049 {
05050 return loc;
05051 }
05052
05053 loc = uentry_whereSpecified (e);
05054 return loc;
05055 }
05056
05057 fileloc uentry_whereEither (uentry e)
05058 {
05059 if (uentry_isInvalid (e)) return fileloc_undefined;
05060
05061 if (fileloc_isDefined (e->whereDefined)
05062 && !fileloc_isExternal (e->whereDefined))
05063 {
05064 return e->whereDefined;
05065 }
05066 else if (fileloc_isDefined (e->whereDeclared))
05067 {
05068 return e->whereDeclared;
05069 }
05070 else
05071 {
05072 return e->whereSpecified;
05073 }
05074 }
05075
05076 fileloc uentry_whereSpecified (uentry e)
05077 {
05078 if (uentry_isInvalid (e)) return fileloc_undefined;
05079
05080 return (e->whereSpecified);
05081 }
05082
05083 fileloc uentry_whereDefined (uentry e)
05084 {
05085 if (uentry_isInvalid (e)) return fileloc_undefined;
05086
05087 return (e->whereDefined);
05088 }
05089
05090 fileloc uentry_whereDeclared (uentry e)
05091 {
05092 if (uentry_isInvalid (e)) return fileloc_undefined;
05093
05094 return (e->whereDeclared);
05095 }
05096
05097 fileloc
05098 uentry_whereEarliest (uentry e)
05099 {
05100 if (uentry_isInvalid (e)) return fileloc_undefined;
05101
05102 if (fileloc_isDefined (e->whereSpecified))
05103 {
05104 return (e->whereSpecified);
05105 }
05106 else if (fileloc_isDefined (e->whereDeclared))
05107 {
05108 return (e->whereDeclared);
05109 }
05110 else
05111 {
05112 return e->whereDefined;
05113 }
05114 }
05115
05116 void
05117 uentry_setFunctionDefined (uentry e, fileloc loc)
05118 {
05119 if (uentry_isValid (e))
05120 {
05121 llassert (uentry_isFunction (e));
05122
05123 if (fileloc_isUndefined (e->whereDeclared))
05124 {
05125 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
05126 }
05127
05128 if (!fileloc_isDefined (e->whereDefined))
05129 {
05130 e->whereDefined = fileloc_update (e->whereDefined, loc);
05131 }
05132 }
05133 }
05134
05135 void
05136 uentry_setDeclDef (uentry e, fileloc f)
05137 {
05138 uentry_setDeclared (e, f);
05139
05140 if (!uentry_isFunction (e)
05141 && !(uentry_isVariable (e) && uentry_isExtern (e)))
05142 {
05143 uentry_setDefined (e, f);
05144 }
05145 }
05146
05147 void
05148 uentry_setDeclaredForce (uentry e, fileloc f)
05149 {
05150 llassert (uentry_isValid (e));
05151 e->whereDeclared = fileloc_update (e->whereDeclared, f);
05152 }
05153
05154 void
05155 uentry_setDeclaredForceOnly (uentry e, fileloc f)
05156 {
05157 llassert (uentry_isValid (e));
05158 fileloc_free (e->whereDeclared);
05159 e->whereDeclared = f;
05160 }
05161
05162 void
05163 uentry_setDeclaredOnly (uentry e, fileloc f)
05164 {
05165 fileloc oldloc;
05166
05167 llassert (uentry_isValid (e));
05168 oldloc = e->whereDeclared;
05169
05170 if (fileloc_isDefined (oldloc))
05171 {
05172 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
05173 {
05174 e->whereDeclared = f;
05175 fileloc_free (oldloc);
05176 }
05177 else
05178 {
05179 fileloc_free (f);
05180 }
05181 }
05182 else
05183 {
05184 e->whereDeclared = f;
05185 fileloc_free (oldloc);
05186 }
05187 }
05188
05189 void
05190 uentry_setDeclared (uentry e, fileloc f)
05191 {
05192 fileloc oldloc;
05193
05194 llassert (uentry_isValid (e));
05195 oldloc = e->whereDeclared;
05196
05197 if (fileloc_isDefined (oldloc))
05198 {
05199 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
05200 {
05201 e->whereDeclared = fileloc_update (e->whereDeclared, f);
05202 }
05203 else
05204 {
05205 ;
05206 }
05207 }
05208 else
05209 {
05210 e->whereDeclared = fileloc_update (e->whereDeclared, f);
05211 }
05212 }
05213
05214 void
05215 uentry_clearDefined (uentry e)
05216 {
05217 if (uentry_isValid (e))
05218 {
05219 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
05220 }
05221 }
05222
05223 void
05224 uentry_setDefined (uentry e, fileloc f)
05225 {
05226 fileloc oldloc;
05227
05228 llassert (uentry_isValid (e));
05229 oldloc = e->whereDefined;
05230
05231 if (fileloc_isDefined (oldloc))
05232 {
05233 if (fileloc_isLib (oldloc)
05234 || fileloc_isImport (oldloc)
05235 || fileloc_isBuiltin (oldloc)
05236 || fileloc_isPreproc (oldloc))
05237 {
05238 e->whereDefined = fileloc_update (e->whereDefined, f);
05239 }
05240 else
05241 {
05242 if (fileloc_equal (oldloc, f) || context_processingMacros ())
05243 {
05244 ;
05245 }
05246 else
05247 {
05248 if (optgenerror (FLG_REDEF,
05249 message ("%s %q redefined",
05250 ekind_capName (e->ukind),
05251 uentry_getName (e)),
05252 f))
05253 {
05254 llgenindentmsg (message ("Previous definition of %q",
05255 uentry_getName (e)),
05256 e->whereDefined);
05257 }
05258 }
05259 }
05260 }
05261 else
05262 {
05263 e->whereDefined = fileloc_update (e->whereDefined, f);
05264 }
05265 }
05266
05267 bool
05268 uentry_isCodeDefined (uentry e)
05269 {
05270 return (uentry_isValid (e) && fileloc_isDefined (e->whereDefined));
05271 }
05272
05273 bool
05274 uentry_isDeclared (uentry e)
05275 {
05276 if (uentry_isValid (e))
05277 {
05278 return (fileloc_isDefined (e->whereDeclared));
05279 }
05280
05281 return FALSE;
05282 }
05283
05284 sRef uentry_getSref (uentry e)
05285 {
05286
05287
05288
05289 if (uentry_isInvalid (e)) return sRef_undefined;
05290
05291 return (e->sref);
05292 }
05293
05294 sRef uentry_getOrigSref (uentry e)
05295 {
05296 if (uentry_isValid (e))
05297 {
05298 sRef sr = sRef_copy (uentry_getSref (e));
05299
05300 sRef_resetState (sr);
05301 sRef_clearDerived (sr);
05302
05303 if (uentry_isVariable (e))
05304 {
05305 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
05306 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
05307 }
05308
05309 return (sr);
05310 }
05311 else
05312 {
05313 return sRef_undefined;
05314 }
05315 }
05316
05317
05318
05319
05320
05321 void
05322 uentry_setName (uentry e, cstring n)
05323 {
05324 llassert (uentry_isValid (e));
05325
05326 cstring_free (e->uname);
05327 e->uname = n;
05328 }
05329
05330 void
05331 uentry_setType (uentry e, ctype t)
05332 {
05333 if (uentry_isValid (e))
05334 {
05335 e->utype = t;
05336 sRef_setType (e->sref, t);
05337 }
05338 }
05339
05340 void
05341 uentry_resetParams (uentry ue, uentryList pn)
05342 {
05343 ctype rct;
05344 ctype rettype = ctype_unknown;
05345
05346 llassert (uentry_isValid (ue));
05347
05348 rct = ctype_realType (ue->utype);
05349
05350 if (uentry_isVariable (ue) && (ctype_isFunction (rct) || ctype_isUnknown (rct)))
05351 {
05352 uentry_makeVarFunction (ue);
05353 }
05354
05355 llassert (uentry_isFunction (ue));
05356
05357 if (ctype_isFunction (rct))
05358 {
05359 rettype = ctype_returnValue (rct);
05360 }
05361
05362 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
05363 }
05364
05365 void
05366 uentry_setRefParam (uentry e)
05367 {
05368
05369 if (!uentry_isVar (e))
05370 {
05371 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
05372 }
05373 else
05374 {
05375 if (e->info->var->kind == VKSEFPARAM)
05376 {
05377 e->info->var->kind = VKREFSEFPARAM;
05378 }
05379 else if (e->info->var->kind == VKSEFRETPARAM)
05380 {
05381 e->info->var->kind = VKREFSEFRETPARAM;
05382 }
05383 else if (e->info->var->kind == VKYIELDPARAM)
05384 {
05385 e->info->var->kind = VKREFYIELDPARAM;
05386 }
05387 else
05388 {
05389 e->info->var->kind = VKREFPARAM;
05390 }
05391 }
05392 }
05393
05394 void
05395 uentry_setParam (uentry e)
05396 {
05397 if (!uentry_isVar (e))
05398 {
05399 if (uentry_isElipsisMarker (e))
05400 {
05401
05402 }
05403 else
05404 {
05405 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
05406 }
05407 }
05408 else
05409 {
05410 cstring oldname;
05411
05412 if (e->info->var->kind == VKYIELDPARAM
05413 || e->info->var->kind == VKSEFPARAM
05414 || e->info->var->kind == VKSEFRETPARAM)
05415 {
05416 ;
05417 }
05418 else
05419 {
05420 e->info->var->kind = VKPARAM;
05421 }
05422
05423 oldname = e->uname;
05424 e->uname = makeParam (e->uname);
05425 cstring_free (oldname);
05426 }
05427 }
05428
05429 void
05430 uentry_setSref (uentry e, sRef s)
05431 {
05432 if (uentry_isValid (e))
05433 {
05434 if (sRef_isValid (e->sref))
05435 {
05436 sRef_mergeStateQuietReverse (e->sref, s);
05437 }
05438 else
05439 {
05440 e->sref = sRef_saveCopy (s);
05441 }
05442 }
05443 }
05444
05445 ctype
05446 uentry_getAbstractType (uentry e)
05447 {
05448 llassert (uentry_isDatatype (e));
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460 if (ctype_isUndefined (e->info->datatype->type))
05461 {
05462 return ctype_unknown;
05463 }
05464
05465
05466
05467
05468
05469 if (ctype_isUserBool (e->info->datatype->type)) {
05470 return ctype_bool;
05471 }
05472
05473 return e->info->datatype->type;
05474 }
05475
05476 ctype uentry_getRealType (uentry e)
05477 {
05478 ctype ct;
05479 typeId uid = USYMIDINVALID;
05480
05481 if (uentry_isInvalid (e))
05482 {
05483 return ctype_unknown;
05484 }
05485
05486 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
05487
05488 if (uentry_isAnyTag (e))
05489 {
05490 return (e->utype);
05491 }
05492
05493 if (uentry_isAbstractType (e))
05494 {
05495 ct = uentry_getAbstractType (e);
05496
05497 if (ctype_isManifestBool (ct)) {
05498 return ct;
05499 }
05500
05501 llassert (ctype_isUA (ct));
05502
05503 uid = ctype_typeId (ct);
05504
05505 if (!context_hasAccess (uid))
05506 {
05507 return (ct);
05508 }
05509 }
05510
05511 ct = uentry_getType (e);
05512
05513
05514
05515 if (ctype_isManifestBool (ct)) {
05516 return ctype_bool;
05517 }
05518
05519 if (ctype_isUA (ct))
05520 {
05521 usymId iid = ctype_typeId (ct);
05522
05523 if (iid == uid)
05524 {
05525 llcontbug (message ("uentry_getRealType: recursive type! %s",
05526 ctype_unparse (ct)));
05527 return ct;
05528 }
05529 else
05530 {
05531
05532 uentry ue2 = usymtab_getTypeEntry (iid);
05533 llassertprint (ue2 != e, ("Bad recursion: %s", uentry_unparseFull (e)));
05534
05535 return uentry_getRealType (ue2);
05536 }
05537 }
05538 else
05539 {
05540 return ct;
05541 }
05542 }
05543
05544 ctype uentry_getForceRealType (uentry e)
05545 {
05546 ctype ct;
05547 typeId uid = USYMIDINVALID;
05548
05549 if (uentry_isInvalid (e))
05550 {
05551 return ctype_unknown;
05552 }
05553
05554 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
05555
05556 if (uentry_isAnyTag (e))
05557 {
05558 return (e->utype);
05559 }
05560
05561 if (uentry_isAbstractType (e))
05562 {
05563 ct = uentry_getAbstractType (e);
05564 llassert (ctype_isUA (ct));
05565
05566 uid = ctype_typeId (ct);
05567
05568 }
05569
05570 ct = uentry_getType (e);
05571
05572
05573
05574
05575 if (ctype_isManifestBool (ct)) {
05576 return ctype_bool;
05577 }
05578
05579 if (ctype_isUA (ct))
05580 {
05581 usymId iid = ctype_typeId (ct);
05582
05583 if (iid == uid)
05584 {
05585 llcontbug (message ("uentry_getRealType: recursive type! %s",
05586 ctype_unparse (ct)));
05587 return ct;
05588 }
05589 else
05590 {
05591 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
05592 }
05593 }
05594 else
05595 {
05596 return ct;
05597 }
05598 }
05599
05600 uentry uentry_nameCopy (cstring name, uentry e)
05601 {
05602 uentry enew = uentry_alloc ();
05603
05604 llassert (uentry_isValid (e));
05605
05606
05607 enew->ukind = e->ukind;
05608 enew->uname = name;
05609 enew->utype = e->utype;
05610 enew->whereSpecified = fileloc_copy (e->whereSpecified);
05611 enew->whereDefined = fileloc_copy (e->whereDefined);
05612 enew->whereDeclared = fileloc_copy (e->whereDeclared);
05613 enew->sref = sRef_copy (e->sref);
05614 enew->used = e->used;
05615 enew->lset = FALSE;
05616 enew->isPrivate = e->isPrivate;
05617 enew->hasNameError = FALSE;
05618
05619 enew->uses = filelocList_new ();
05620
05621 enew->storageclass = e->storageclass;
05622 enew->info = uinfo_copy (e->info, e->ukind);
05623
05624 return enew;
05625 }
05626
05627 void
05628 uentry_setDatatype (uentry e, usymId uid)
05629 {
05630 llassert (uentry_isDatatype (e));
05631
05632 if (uentry_isAbstractType (e))
05633 {
05634 e->info->datatype->type = ctype_createAbstract (uid);
05635 }
05636 else
05637 {
05638 e->info->datatype->type = ctype_createUser (uid);
05639 }
05640 }
05641
05642 static void
05643 uentry_setSpecDef ( uentry e, fileloc f)
05644
05645
05646 {
05647 llassert (uentry_isValid (e));
05648
05649 if (fileloc_isSpec (f) || fileloc_isImport (f))
05650 {
05651 e->whereSpecified = f;
05652 e->whereDeclared = fileloc_undefined;
05653 e->whereDefined = fileloc_undefined;
05654 }
05655 else
05656 {
05657 e->whereSpecified = fileloc_undefined;
05658 e->whereDeclared = f;
05659 e->whereDefined = fileloc_undefined;
05660 }
05661 }
05662
05663 static void
05664 ucinfo_free ( ucinfo u)
05665 {
05666 multiVal_free (u->val);
05667 sfree (u);
05668 }
05669
05670 static void
05671 uvinfo_free ( uvinfo u)
05672 {
05673 sfree (u);
05674 }
05675
05676 static void
05677 udinfo_free ( udinfo u)
05678 {
05679 sfree (u);
05680 }
05681
05682 static void
05683 ufinfo_free ( ufinfo u)
05684 {
05685 globSet_free (u->globs);
05686 sRefSet_free (u->mods);
05687 specialClauses_free (u->specclauses);
05688
05689 sfree (u);
05690 }
05691
05692 static void
05693 uiinfo_free ( uiinfo u)
05694 {
05695 sfree (u);
05696 }
05697
05698 static void
05699 ueinfo_free ( ueinfo u)
05700 {
05701 sfree (u);
05702 }
05703
05704 static ucinfo
05705 ucinfo_copy (ucinfo u)
05706 {
05707 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
05708
05709 ret->val = multiVal_copy (u->val);
05710 ret->access = u->access;
05711
05712 return ret;
05713 }
05714
05715 static uvinfo
05716 uvinfo_copy (uvinfo u)
05717 {
05718 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
05719
05720 ret->kind = u->kind;
05721 ret->nullstate = u->nullstate;
05722 ret->defstate = u->defstate;
05723 ret->checked = u->checked;
05724
05725 return ret;
05726 }
05727
05728 static udinfo
05729 udinfo_copy (udinfo u)
05730 {
05731 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
05732
05733 ret->abs = u->abs;
05734 ret->mut = u->mut;
05735 ret->type = u->type;
05736
05737 return ret;
05738 }
05739
05740 static ufinfo
05741 ufinfo_copy (ufinfo u)
05742 {
05743 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
05744
05745 ret->hasGlobs = u->hasGlobs;
05746 ret->hasMods = u->hasMods;
05747 ret->exitCode = u->exitCode;
05748 ret->specialCode = u->specialCode;
05749 ret->nullPred = u->nullPred;
05750 ret->access = u->access;
05751 ret->globs = globSet_newCopy (u->globs);
05752 ret->mods = sRefSet_newCopy (u->mods);
05753 ret->defparams = u->defparams;
05754 ret->specclauses = specialClauses_copy (u->specclauses);
05755
05756 return ret;
05757 }
05758
05759 static uiinfo
05760 uiinfo_copy (uiinfo u)
05761 {
05762 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
05763
05764 ret->access = u->access;
05765 ret->globs = globSet_newCopy (u->globs);
05766 ret->mods = sRefSet_newCopy (u->mods);
05767
05768 return (ret);
05769 }
05770
05771 static ueinfo
05772 ueinfo_copy (ueinfo u)
05773 {
05774 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
05775
05776 ret->access = u->access;
05777 return ret;
05778 }
05779
05780 static void
05781 uinfo_free (uinfo u, ekind kind)
05782 {
05783 switch (kind)
05784 {
05785 case KENUMCONST:
05786 case KCONST: ucinfo_free (u->uconst); break;
05787 case KVAR: uvinfo_free (u->var); break;
05788 case KSTRUCTTAG:
05789 case KUNIONTAG:
05790 case KENUMTAG:
05791 case KDATATYPE: udinfo_free (u->datatype); break;
05792 case KFCN: ufinfo_free (u->fcn); break;
05793 case KITER: uiinfo_free (u->iter); break;
05794 case KENDITER: ueinfo_free (u->enditer); break;
05795 case KELIPSMARKER: break;
05796 case KINVALID: break;
05797 }
05798
05799 sfree (u);
05800 }
05801
05802 static uinfo
05803 uinfo_copy (uinfo u, ekind kind)
05804 {
05805 if (kind == KELIPSMARKER || kind == KINVALID)
05806 {
05807 return NULL;
05808 }
05809 else
05810 {
05811 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
05812
05813 switch (kind)
05814 {
05815 case KENUMCONST:
05816 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
05817 case KVAR: ret->var = uvinfo_copy (u->var); break;
05818 case KSTRUCTTAG:
05819 case KUNIONTAG:
05820 case KENUMTAG:
05821 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
05822 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
05823 case KITER: ret->iter = uiinfo_copy (u->iter); break;
05824 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
05825 BADDEFAULT;
05826 }
05827 return ret;
05828 }
05829 }
05830
05831 static void
05832 uentry_reallyFree ( uentry e)
05833 {
05834 filelocList_free (e->uses);
05835 cstring_free (e->uname);
05836
05837 uinfo_free (e->info, e->ukind);
05838
05839 fileloc_free (e->whereSpecified);
05840 fileloc_free (e->whereDefined);
05841 fileloc_free (e->whereDeclared);
05842
05843 nuentries--;
05844 sfree (e);
05845 }
05846
05847 extern void uentry_markOwned ( uentry u)
05848 {
05849 sfreeEventually (u);
05850 }
05851
05852 void
05853 uentry_free ( uentry e)
05854 {
05855 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
05856 {
05857 uentry_reallyFree (e);
05858 }
05859 }
05860
05861
05862
05863
05864
05865 void
05866 uentry_freeComplete ( uentry e)
05867 {
05868 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
05869 {
05870 sRef_free (e->sref);
05871 e->sref = sRef_undefined;
05872 uentry_reallyFree (e);
05873 }
05874 }
05875
05876
05877
05878
05879
05880 static void
05881 KindConformanceError ( uentry old, uentry unew, bool mustConform)
05882 {
05883 llassert (uentry_isValid (old));
05884 llassert (uentry_isValid (unew));
05885
05886 if (uentry_isEitherConstant (unew)
05887 && (fileloc_isPreproc (uentry_whereDeclared (old))
05888 || ctype_isUnknown (old->utype))
05889 && !uentry_isSpecified (old))
05890 {
05891 ;
05892 }
05893 else
05894 {
05895 if (mustConform)
05896 {
05897 if (!uentry_isDeclared (old))
05898 {
05899 if (uentry_isSpecified (old))
05900 {
05901 if (uentry_isSpecified (unew))
05902 {
05903 llbuglit ("Respecification!");
05904 }
05905 else if (uentry_isDeclared (unew))
05906 {
05907 if (optgenerror
05908 (FLG_INCONDEFS,
05909 message ("%s %q inconsistently declared as %s: %t",
05910 ekind_capName (old->ukind),
05911 uentry_getName (unew),
05912 ekind_unparseLong (unew->ukind),
05913 unew->utype),
05914 uentry_whereDeclared (unew)))
05915 {
05916 uentry_showWhereLast (old);
05917 }
05918 }
05919 else
05920 {
05921 BADEXIT;
05922 }
05923 }
05924 else
05925 {
05926 if (optgenerror
05927 (FLG_INCONDEFS,
05928 message ("%s %q inconsistently declared as %s: %t",
05929 ekind_capName (old->ukind),
05930 uentry_getName (unew),
05931 ekind_unparseLong (unew->ukind),
05932 unew->utype),
05933 uentry_whereDeclared (unew)))
05934 {
05935 uentry_showWhereLast (old);
05936 }
05937 }
05938 }
05939 else
05940 {
05941 llassert (uentry_isDeclared (unew));
05942
05943 if (optgenerror
05944 (FLG_INCONDEFS,
05945 message ("%s %q inconsistently redeclared as %s",
05946 ekind_capName (old->ukind),
05947 uentry_getName (unew),
05948 ekind_unparseLong (unew->ukind)),
05949 uentry_whereDeclared (unew)))
05950 {
05951 uentry_showWhereLast (old);
05952 }
05953 }
05954 }
05955 }
05956
05957 uentry_copyInto (old, unew);
05958 }
05959
05960
05961
05962
05963
05964
05965
05966
05967
05968 void
05969 uentry_showWhereLast (uentry spec)
05970 {
05971 if (uentry_isValid (spec))
05972 {
05973 if (fileloc_isDefined (spec->whereDefined)
05974 && !fileloc_isLib (spec->whereDefined)
05975 && !fileloc_isPreproc (spec->whereDefined))
05976 {
05977 llgenindentmsg (message ("Previous definition of %q: %t",
05978 uentry_getName (spec),
05979 uentry_getType (spec)),
05980 uentry_whereDefined (spec));
05981 }
05982 else if (uentry_isDeclared (spec))
05983 {
05984 llgenindentmsg (message ("Previous declaration of %q: %t",
05985 uentry_getName (spec),
05986 uentry_getType (spec)),
05987 uentry_whereDeclared (spec));
05988 }
05989 else if (uentry_isSpecified (spec))
05990 {
05991 if (uentry_hasName (spec))
05992 {
05993 llgenindentmsg (message ("Specification of %q: %t",
05994 uentry_getName (spec),
05995 uentry_getType (spec)),
05996 uentry_whereSpecified (spec));
05997 }
05998 else
05999 {
06000 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
06001 uentry_whereSpecified (spec));
06002 }
06003 }
06004 else
06005 {
06006
06007 }
06008 }
06009 }
06010
06011 void
06012 uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
06013 {
06014 fileloc loc = uentry_whereDefined (ce);
06015
06016 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
06017 {
06018 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
06019 loc);
06020 }
06021
06022 loc = uentry_whereSpecified (ce);
06023
06024 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
06025 {
06026 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
06027 loc);
06028 }
06029 }
06030
06031 void uentry_showWhereLastExtra (uentry spec, cstring extra)
06032 {
06033 if (uentry_isDeclared (spec))
06034 {
06035 llgenindentmsg (message ("Previous declaration of %q: %q",
06036 uentry_getName (spec), extra),
06037 uentry_whereDeclared (spec));
06038 }
06039 else if (uentry_isSpecified (spec))
06040 {
06041 llgenindentmsg (message ("Specification of %q: %q",
06042 uentry_getName (spec), extra),
06043 uentry_whereSpecified (spec));
06044 }
06045 else
06046 {
06047 cstring_free (extra);
06048 }
06049 }
06050
06051 void
06052 uentry_showWhereDeclared (uentry spec)
06053 {
06054 if (uentry_isDeclared (spec))
06055 {
06056 if (uentry_hasName (spec))
06057 {
06058 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
06059 uentry_whereDeclared (spec));
06060 }
06061 else
06062 {
06063 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
06064 }
06065 }
06066 else if (uentry_isSpecified (spec))
06067 {
06068 if (uentry_hasName (spec))
06069 {
06070 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
06071 uentry_whereSpecified (spec));
06072 }
06073 else
06074 {
06075 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
06076 }
06077 }
06078 else
06079 {
06080
06081 }
06082
06083 }
06084
06085 void
06086 uentry_showWhereAny (uentry spec)
06087 {
06088 if (uentry_isDeclared (spec))
06089 {
06090 if (uentry_hasName (spec))
06091 {
06092 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
06093 uentry_whereDeclared (spec));
06094 }
06095 else
06096 {
06097 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
06098 }
06099 }
06100 else if (uentry_isSpecified (spec))
06101 {
06102 if (uentry_hasName (spec))
06103 {
06104 llgenindentmsg (message ("Specification of %q",
06105 uentry_getName (spec)),
06106 uentry_whereSpecified (spec));
06107 }
06108 else
06109 {
06110 llgenindentmsg (cstring_makeLiteral ("Specification"),
06111 uentry_whereSpecified (spec));
06112 }
06113 }
06114 else if (fileloc_isDefined (uentry_whereDefined (spec)))
06115 {
06116 if (uentry_hasName (spec))
06117 {
06118 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
06119 uentry_whereDefined (spec));
06120 }
06121 else
06122 {
06123 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
06124 }
06125 }
06126 else
06127 {
06128
06129 }
06130 }
06131
06132 void
06133 uentry_showWhereDefined (uentry spec)
06134 {
06135 if (uentry_isCodeDefined (spec))
06136 {
06137 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
06138 uentry_whereDefined (spec));
06139 }
06140 }
06141
06142 void
06143 uentry_showWhereLastPlain (uentry spec)
06144 {
06145 if (uentry_isDeclared (spec))
06146 {
06147 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
06148 uentry_whereDeclared (spec));
06149 }
06150 else if (uentry_isSpecified (spec))
06151 {
06152 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
06153 uentry_whereSpecified (spec));
06154 }
06155 else
06156 {
06157 }
06158 }
06159
06160 static void
06161 uentry_showWhereLastVal (uentry spec, cstring val)
06162 {
06163 if (uentry_isDeclared (spec))
06164 {
06165 llgenindentmsg (message ("Previous declaration of %q: %s",
06166 uentry_getName (spec), val),
06167 uentry_whereDeclared (spec));
06168 }
06169 else if (uentry_isSpecified (spec))
06170 {
06171 llgenindentmsg (message ("Specification of %q: %s",
06172 uentry_getName (spec), val),
06173 uentry_whereSpecified (spec));
06174 }
06175 else
06176 {
06177 }
06178 }
06179
06180 void
06181 uentry_showWhereSpecified (uentry spec)
06182 {
06183 if (uentry_isSpecified (spec))
06184 {
06185 if (uentry_hasName (spec))
06186 {
06187 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
06188 uentry_whereSpecified (spec));
06189 }
06190 else
06191 {
06192 llgenindentmsg (cstring_makeLiteral ("Specification"),
06193 uentry_whereSpecified (spec));
06194 }
06195 }
06196 else if (uentry_isDeclared (spec))
06197 {
06198 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
06199 uentry_whereDeclared (spec));
06200 }
06201 else
06202 {
06203
06204 }
06205 }
06206
06207 void
06208 uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
06209 {
06210 if (uentry_isSpecified (spec))
06211 {
06212 if (uentry_hasName (spec))
06213 {
06214 llgenindentmsg (message ("Specification of %q: %q",
06215 uentry_getName (spec), s),
06216 uentry_whereSpecified (spec));
06217 }
06218 else
06219 {
06220 llgenindentmsg (message ("Specification: %q", s),
06221 uentry_whereSpecified (spec));
06222 }
06223 }
06224 else if (uentry_isDeclared (spec))
06225 {
06226 llgenindentmsg (message ("Declaration of %q: %q",
06227 uentry_getName (spec), s),
06228 uentry_whereDeclared (spec));
06229 }
06230 else
06231 {
06232 llgenindentmsg (message ("Previous: %q", s),
06233 uentry_whereLast (spec));
06234 }
06235 }
06236
06237
06238
06239
06240
06241 static void
06242 checkStructConformance (uentry old, uentry unew)
06243 {
06244 ctype oldr, newr;
06245 uentryList fold, fnew;
06246
06247
06248
06249
06250
06251 llassert (uentry_isValid (old));
06252 llassert (uentry_isValid (unew));
06253
06254 oldr = ctype_realType (old->utype);
06255 fold = ctype_getFields (oldr);
06256
06257 newr = ctype_realType (unew->utype);
06258 fnew = ctype_getFields (newr);
06259
06260 if (!uentryList_matchFields (fold, fnew))
06261 {
06262 if (fileloc_equal (uentry_whereLast (old),
06263 uentry_whereLast (unew)))
06264 {
06265 ;
06266 }
06267 else
06268 {
06269 if (optgenerror
06270 (FLG_MATCHFIELDS,
06271 message ("%q %q %rdeclared with fields { %q }, %s "
06272 "with fields { %q }",
06273 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
06274 uentry_getName (old),
06275 uentry_isDeclared (old),
06276 uentryList_unparseAbbrev (fnew),
06277 uentry_specOrDefName (old),
06278 uentryList_unparseAbbrev (fold)),
06279 uentry_whereDeclared (unew)))
06280 {
06281 uentry_showWhereLastPlain (old);
06282 uentryList_showFieldDifference (fold, fnew);
06283 }
06284 }
06285
06286 old->utype = unew->utype;
06287 }
06288 }
06289
06290 static void
06291 checkEnumConformance ( uentry old, uentry unew)
06292 {
06293
06294
06295
06296
06297 ctype rold = ctype_realType (old->utype);
06298 ctype rnew = ctype_realType (unew->utype);
06299 enumNameList eold = ctype_elist (rold);
06300 enumNameList enew = ctype_elist (rnew);
06301
06302 if (!enumNameList_match (eold, enew))
06303 {
06304 if (optgenerror
06305 (FLG_MATCHFIELDS,
06306 message ("Enum %q declared with members { %q } but "
06307 "specified with members { %q }",
06308 uentry_getName (old),
06309 enumNameList_unparse (enew),
06310 enumNameList_unparse (eold)),
06311 uentry_whereDeclared (unew)))
06312 {
06313 uentry_showWhereSpecified (old);
06314 old->utype = unew->utype;
06315 }
06316 }
06317 }
06318
06319
06320
06321
06322
06323 static void
06324 paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
06325 uentry unew, uentry newCurrent, ctype newType,
06326 int paramno)
06327 {
06328 bool hasError = FALSE;
06329
06330 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
06331 {
06332 if (uentry_hasName (newCurrent))
06333 {
06334 hasError = optgenerror
06335 (FLG_TYPE,
06336 message ("Parameter %d, %q, of function %q has inconsistent type: "
06337 "declared %t, %s %t",
06338 paramno + 1, uentry_getName (newCurrent),
06339 uentry_getName (unew),
06340 newType, uentry_specOrDefName (old), oldType),
06341 uentry_whereDeclared (newCurrent));
06342 }
06343 else
06344 {
06345 hasError = optgenerror
06346 (FLG_TYPE,
06347 message ("Parameter %d of function %q has inconsistent type: "
06348 "declared %t, %s %t",
06349 paramno + 1, uentry_getName (unew),
06350 newType, uentry_specOrDefName (old), oldType),
06351 uentry_whereDeclared (newCurrent));
06352
06353 DPRINTF (("type: %s / %s",
06354 ctype_unparse (newType),
06355 ctype_unparse (ctype_realType (newType))));
06356 }
06357 }
06358 else
06359 {
06360 if (uentry_isDeclared (unew))
06361 {
06362 hasError = optgenerror
06363 (FLG_TYPE,
06364 message ("Parameter %d of function %s has inconsistent type: "
06365 "declared %t, %s %t",
06366 paramno + 1, unew->uname,
06367 newType, uentry_specOrDefName (old), oldType),
06368 uentry_whereDeclared (unew));
06369 }
06370 else
06371 {
06372 hasError = optgenerror
06373 (FLG_TYPE,
06374 message ("Parameter %d of function %s has inconsistent type: "
06375 "declared %t, %s %t",
06376 paramno + 1, unew->uname,
06377 newType, uentry_specOrDefName (old), oldType),
06378 uentry_whereDeclared (unew));
06379 }
06380 }
06381
06382 if (hasError)
06383 {
06384 if (!uentry_isUndefined (oldCurrent))
06385 {
06386 if (!uentry_isUndefined (newCurrent)
06387 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
06388 {
06389 uentry_showWhereLast (oldCurrent);
06390 }
06391 else
06392 {
06393 uentry_showWhereLastPlain (old);
06394 }
06395
06396 uentry_setType (oldCurrent, newType);
06397 }
06398 else
06399 {
06400 uentry_showWhereLastPlain (old);
06401 }
06402 }
06403 }
06404
06405 static void
06406 nargsError ( uentry old, uentry unew)
06407 {
06408 if (optgenerror
06409 (FLG_TYPE,
06410 message ("Function %s %rdeclared with %d arg%p, %s with %d",
06411 unew->uname,
06412 uentry_isDeclared (old),
06413 uentryList_size (uentry_getParams (unew)),
06414 uentry_specOrDefName (old),
06415 uentryList_size (uentry_getParams (old))),
06416 uentry_whereDeclared (unew)))
06417 {
06418 uentry_showWhereLastPlain (old);
06419 }
06420 }
06421
06422 static void
06423 returnValueError ( uentry old, uentry unew)
06424 {
06425 if (optgenerror
06426 (FLG_INCONDEFS,
06427 message ("Function %s inconsistently %rdeclared to return %t",
06428 unew->uname,
06429 uentry_isDeclared (old),
06430 ctype_returnValue (unew->utype)),
06431 uentry_whereDeclared (unew)))
06432 {
06433 uentry_showWhereLastVal (old, ctype_unparse (ctype_returnValue (old->utype)));
06434 }
06435 }
06436
06437 static cstring paramStorageName (uentry ue)
06438 {
06439 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
06440 }
06441
06442 static cstring fcnErrName (uentry ue)
06443 {
06444 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
06445 }
06446
06447 extern cstring uentry_checkedName (uentry ue)
06448 {
06449 if (uentry_isVar (ue))
06450 {
06451 return (checkedName (ue->info->var->checked));
06452 }
06453 else
06454 {
06455 return (cstring_makeLiteralTemp ("<checked invalid>"));
06456 }
06457 }
06458
06459 static cstring checkedName (chkind checked)
06460 {
06461 switch (checked)
06462 {
06463 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
06464 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
06465 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
06466 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
06467 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
06468 }
06469 BADEXIT;
06470 }
06471
06472 static
06473 void checkNullState ( uentry old, uentry unew, bool mustConform, bool completeConform)
06474 {
06475 nstate oldState;
06476 nstate newState;
06477
06478 if (uentry_isVar (unew))
06479 {
06480 llassert (uentry_isVar (old));
06481
06482 oldState = old->info->var->nullstate;
06483 newState = unew->info->var->nullstate;
06484 }
06485 else
06486 {
06487 oldState = sRef_getNullState (old->sref);
06488 newState = sRef_getNullState (unew->sref);
06489 }
06490
06491 if (oldState == NS_ABSNULL)
06492 {
06493 if (uentry_isVar (old))
06494 {
06495 old->info->var->nullstate = newState;
06496 }
06497
06498 sRef_mergeNullState (old->sref, newState);
06499 }
06500 else if (newState == NS_UNKNOWN)
06501 {
06502 if (completeConform && newState != oldState
06503 && uentry_isReallySpecified (old))
06504 {
06505 if (optgenerror
06506 (FLG_NEEDSPEC,
06507 message ("%s %q specified as %s, but declared without %s qualifier",
06508 ekind_capName (unew->ukind),
06509 uentry_getName (unew),
06510 nstate_unparse (oldState),
06511 nstate_unparse (oldState)),
06512 uentry_whereDeclared (unew)))
06513 {
06514 uentry_showWhereSpecified (old);
06515 }
06516 }
06517
06518 if (uentry_isVar (unew))
06519 {
06520 unew->info->var->nullstate = oldState;
06521 }
06522
06523 sRef_mergeNullState (unew->sref, oldState);
06524 }
06525 else if (newState == NS_POSNULL)
06526 {
06527 if (oldState == NS_MNOTNULL
06528 && (ctype_isUA (unew->utype)
06529 || (uentry_isFunction (unew)
06530 && ctype_isUA (ctype_returnValue (unew->utype)))))
06531 {
06532 if (uentry_isVar (unew))
06533 {
06534 unew->info->var->nullstate = oldState;
06535 }
06536
06537 sRef_mergeNullState (unew->sref, oldState);
06538 }
06539 else
06540 {
06541 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
06542 || oldState == NS_UNKNOWN)
06543 {
06544 if (mustConform)
06545 {
06546 if (optgenerror
06547 (FLG_INCONDEFS,
06548 message
06549 ("%s %q inconsistently %rdeclared %s possibly null storage, "
06550 "%s %q qualifier",
06551 uentry_ekindName (unew),
06552 uentry_getName (unew),
06553 uentry_isDeclared (old),
06554 fcnErrName (unew),
06555 uentry_specOrDefName (old),
06556 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
06557 uentry_whereDeclared (unew)))
06558 {
06559 uentry_showWhereSpecified (old);
06560 }
06561 }
06562 }
06563
06564 if (uentry_isVar (old))
06565 {
06566 old->info->var->nullstate = newState;
06567 }
06568
06569 sRef_mergeNullState (old->sref, newState);
06570 }
06571 }
06572 else if (newState == NS_MNOTNULL)
06573 {
06574 if (oldState != NS_MNOTNULL)
06575 {
06576 if (mustConform)
06577 {
06578 if (optgenerror
06579 (FLG_INCONDEFS,
06580 message ("%s %q inconsistently %rdeclared %s notnull storage, "
06581 "%s without notnull qualifier",
06582 uentry_ekindName (unew),
06583 uentry_getName (unew),
06584 uentry_isDeclared (old),
06585 fcnErrName (unew),
06586 uentry_specOrDefName (old)),
06587 uentry_whereDeclared (unew)))
06588 {
06589 uentry_showWhereSpecified (old);
06590 }
06591 }
06592
06593 if (uentry_isVar (old))
06594 {
06595 old->info->var->nullstate = newState;
06596 }
06597
06598 sRef_mergeNullState (old->sref, newState);
06599 }
06600 }
06601 else
06602 {
06603 if (uentry_isVar (unew))
06604 {
06605 unew->info->var->nullstate = oldState;
06606 }
06607
06608 sRef_mergeNullState (unew->sref, oldState);
06609 }
06610 }
06611
06612 static
06613 void checkDefState ( uentry old, uentry unew,
06614 bool mustConform, bool completeConform)
06615 {
06616 sstate oldState;
06617 sstate newState;
06618 bool vars = FALSE;
06619
06620 if (uentry_isVar (old) && uentry_isVar (unew))
06621 {
06622 oldState = old->info->var->defstate;
06623 newState = unew->info->var->defstate;
06624 vars = TRUE;
06625 }
06626 else
06627 {
06628 oldState = sRef_getDefState (old->sref);
06629 newState = sRef_getDefState (unew->sref);
06630 }
06631
06632 if (newState != oldState && newState != SS_UNKNOWN && newState != SS_DEFINED)
06633 {
06634 if (mustConform)
06635 {
06636 if (optgenerror
06637 (FLG_INCONDEFS,
06638 message ("%s %q inconsistently %rdeclared %s %s %s, "
06639 "%s %s %s %s",
06640 uentry_ekindName (unew),
06641 uentry_getName (unew),
06642 uentry_isDeclared (old),
06643 fcnErrName (unew),
06644 sstate_unparse (newState),
06645 paramStorageName (unew),
06646 uentry_specOrDefName (old),
06647 fcnErrName (unew),
06648 sstate_unparse (oldState),
06649 paramStorageName (unew)),
06650 uentry_whereDeclared (unew)))
06651 {
06652 uentry_showWhereSpecified (old);
06653 }
06654 }
06655
06656 if (vars) old->info->var->defstate = newState;
06657 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
06658 }
06659 else
06660 {
06661 if (completeConform
06662 && (newState != oldState) && (oldState != SS_DEFINED)
06663 && uentry_isReallySpecified (old))
06664 {
06665 if (optgenerror
06666 (FLG_NEEDSPEC,
06667 message ("%s %q specified as %s, but declared without %s qualifier",
06668 ekind_capName (unew->ukind),
06669 uentry_getName (unew),
06670 sstate_unparse (oldState),
06671 sstate_unparse (oldState)),
06672 uentry_whereDeclared (unew)))
06673 {
06674 uentry_showWhereSpecified (old);
06675 }
06676 }
06677
06678 if (vars) unew->info->var->defstate = oldState;
06679 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
06680 }
06681 }
06682
06683 static void
06684 checkAliasState ( uentry old, uentry unew,
06685 bool mustConform, bool completeConform)
06686 {
06687 alkind newKind;
06688 alkind oldKind;
06689
06690 oldKind = sRef_getAliasKind (old->sref);
06691 newKind = sRef_getAliasKind (unew->sref);
06692
06693 if (alkind_isImplicit (newKind)
06694 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
06695 {
06696 if (completeConform && !alkind_equal (newKind, oldKind)
06697 && uentry_isReallySpecified (old))
06698 {
06699 if (optgenerror
06700 (FLG_NEEDSPEC,
06701 message ("%s %q specified as %s, but declared without "
06702 "explicit alias qualifier",
06703 ekind_capName (unew->ukind),
06704 uentry_getName (unew),
06705 alkind_unparse (oldKind)),
06706 uentry_whereDeclared (unew)))
06707 {
06708 uentry_showWhereSpecified (old);
06709 }
06710 }
06711
06712
06713
06714
06715
06716
06717 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
06718 return;
06719 }
06720
06721 if (alkind_isKnown (newKind))
06722 {
06723 if (!alkind_equal (oldKind, newKind))
06724 {
06725 if (alkind_isKnown (oldKind))
06726 {
06727 if (mustConform &&
06728 optgenerror
06729 (FLG_INCONDEFS,
06730 message ("%s %q inconsistently %rdeclared %s %s storage, "
06731 "%s as %s storage",
06732 uentry_ekindName (unew),
06733 uentry_getName (unew),
06734 uentry_isDeclared (old),
06735 fcnErrName (unew),
06736 alkind_unparse (newKind),
06737 uentry_specOrDefName (old),
06738 alkind_unparse (oldKind)),
06739 uentry_whereDeclared (unew)))
06740 {
06741 uentry_showWhereSpecified (old);
06742
06743 sRef_setAliasKind (old->sref, AK_ERROR,
06744 uentry_whereDeclared (unew));
06745 }
06746 else
06747 {
06748 sRef_setAliasKind (old->sref, newKind,
06749 uentry_whereDeclared (unew));
06750 }
06751 }
06752 else
06753 {
06754 if (!(alkind_isImplicit (newKind)))
06755 {
06756 if (mustConform &&
06757 !uentry_isFunction (unew) &&
06758 optgenerror
06759 (FLG_INCONDEFS,
06760 message ("%s %q inconsistently %rdeclared %s %s storage, "
06761 "implicitly %s as temp storage",
06762 uentry_ekindName (unew),
06763 uentry_getName (unew),
06764 uentry_isDeclared (old),
06765 fcnErrName (unew),
06766 alkind_unparse (newKind),
06767 uentry_specOrDefName (old)),
06768 uentry_whereDeclared (unew)))
06769 {
06770 uentry_showWhereSpecified (old);
06771 oldKind = AK_ERROR;
06772 }
06773
06774 sRef_setAliasKind (old->sref, newKind,
06775 uentry_whereDeclared (unew));
06776 }
06777 else
06778 {
06779 ;
06780 }
06781 }
06782 }
06783 }
06784 else
06785 {
06786 ;
06787 }
06788 }
06789
06790 static void
06791 checkExpState( uentry old, uentry unew,
06792 bool mustConform, bool completeConform)
06793 {
06794 exkind newKind;
06795 exkind oldKind;
06796
06797 oldKind = sRef_getExKind (old->sref);
06798 newKind = sRef_getExKind (unew->sref);
06799
06800 if (exkind_isKnown (newKind))
06801 {
06802 if (oldKind != newKind)
06803 {
06804 if (exkind_isKnown (oldKind))
06805 {
06806 if (mustConform &&
06807 optgenerror
06808 (FLG_INCONDEFS,
06809 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
06810 uentry_ekindName (unew),
06811 uentry_getName (unew),
06812 uentry_isDeclared (old),
06813 fcnErrName (unew),
06814 exkind_unparse (newKind),
06815 uentry_specOrDefName (old),
06816 exkind_unparse (oldKind)),
06817 uentry_whereDeclared (unew)))
06818 {
06819 uentry_showWhereSpecified (old);
06820 }
06821
06822 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
06823 }
06824 else
06825 {
06826 if (mustConform &&
06827 optgenerror
06828 (FLG_INCONDEFS,
06829 message ("%s %q inconsistently %rdeclared %s %s, "
06830 "implicitly %s without exposure qualifier",
06831 uentry_ekindName (unew),
06832 uentry_getName (unew),
06833 uentry_isDeclared (old),
06834 fcnErrName (unew),
06835 exkind_unparse (newKind),
06836 uentry_specOrDefName (old)),
06837 uentry_whereDeclared (unew)))
06838 {
06839 uentry_showWhereSpecified (old);
06840 }
06841
06842 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
06843 }
06844 }
06845 }
06846 else
06847 {
06848 if (completeConform && exkind_isKnown (oldKind)
06849 && uentry_isReallySpecified (old))
06850 {
06851 if (optgenerror
06852 (FLG_NEEDSPEC,
06853 message ("%s %q specified as %s, but declared without "
06854 "exposure qualifier",
06855 ekind_capName (unew->ukind),
06856 uentry_getName (unew),
06857 exkind_unparse (oldKind)),
06858 uentry_whereDeclared (unew)))
06859 {
06860 uentry_showWhereSpecified (old);
06861 }
06862 }
06863
06864
06865 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
06866 }
06867 }
06868
06869 static void
06870 uentry_checkStateConformance ( uentry old,
06871 uentry unew,
06872 bool mustConform, bool completeConform)
06873 {
06874 checkDefState (old, unew, mustConform, completeConform);
06875 checkNullState (old, unew, mustConform, completeConform);
06876 checkAliasState (old, unew, mustConform, completeConform);
06877 checkExpState (old, unew, mustConform, completeConform);
06878
06879 sRef_storeState (old->sref);
06880 sRef_storeState (unew->sref);
06881 }
06882
06883 static void
06884 checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
06885 {
06886 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
06887 {
06888 return;
06889 }
06890
06891 llassert (uentry_isVar (old));
06892 llassert (uentry_isVar (unew));
06893
06894 if (cstring_isEmpty (old->uname))
06895 {
06896 cstring_free (old->uname);
06897 old->uname = cstring_copy (unew->uname);
06898 }
06899
06900 if (unew->info->var->kind == VKRETPARAM
06901 || unew->info->var->kind == VKSEFRETPARAM)
06902 {
06903 if (old->info->var->kind != VKRETPARAM
06904 && old->info->var->kind != VKSEFRETPARAM)
06905 {
06906 if (optgenerror
06907 (FLG_INCONDEFS,
06908 message ("Parameter %q inconsistently %rdeclared as "
06909 "returned parameter",
06910 uentry_getName (unew),
06911 uentry_isDeclared (old)),
06912 uentry_whereDeclared (unew)))
06913 {
06914 uentry_showWhereSpecified (old);
06915 old->info->var->kind = unew->info->var->kind;
06916 }
06917 }
06918 }
06919
06920
06921 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
06922 {
06923 if (old->info->var->kind != VKSEFPARAM
06924 && old->info->var->kind != VKSEFRETPARAM)
06925 {
06926 if (optgenerror
06927 (FLG_INCONDEFS,
06928 message ("Parameter %qinconsistently %rdeclared as "
06929 "sef parameter",
06930 uentry_getOptName (unew),
06931 uentry_isDeclared (old)),
06932 uentry_whereDeclared (unew)))
06933 {
06934 uentry_showWhereSpecified (old);
06935 old->info->var->kind = unew->info->var->kind;
06936 }
06937 }
06938 }
06939
06940 if (old->info->var->kind == VKSPEC)
06941 {
06942 old->info->var->kind = unew->info->var->kind;
06943 }
06944 else
06945 {
06946 unew->info->var->kind = old->info->var->kind;
06947 }
06948
06949 if (unew->info->var->checked != CH_UNKNOWN
06950 && unew->info->var->checked != old->info->var->checked)
06951 {
06952 if (old->info->var->checked == CH_UNKNOWN
06953 && !fileloc_isUser (uentry_whereLast (old)))
06954 {
06955 ;
06956 }
06957 else
06958 {
06959 if (optgenerror
06960 (FLG_INCONDEFS,
06961 message ("Variable %q inconsistently %rdeclared as "
06962 "%s parameter (was %s)",
06963 uentry_getName (unew),
06964 uentry_isDeclared (old),
06965 checkedName (unew->info->var->checked),
06966 checkedName (old->info->var->checked)),
06967 uentry_whereDeclared (unew)))
06968 {
06969 uentry_showWhereSpecified (old);
06970 }
06971 }
06972
06973 old->info->var->checked = unew->info->var->checked;
06974 }
06975 else
06976 {
06977 if (completeConform
06978 && (old->info->var->checked != CH_UNKNOWN)
06979 && uentry_isReallySpecified (old))
06980 {
06981 if (optgenerror
06982 (FLG_NEEDSPEC,
06983 message ("%s %q specified as %s, but declared without %s qualifier",
06984 ekind_capName (unew->ukind),
06985 uentry_getName (unew),
06986 checkedName (old->info->var->checked),
06987 checkedName (old->info->var->checked)),
06988 uentry_whereDeclared (unew)))
06989 {
06990 uentry_showWhereSpecified (old);
06991 }
06992 }
06993
06994 unew->info->var->checked = old->info->var->checked;
06995 }
06996
06997 uentry_checkStateConformance (old, unew, mustConform, completeConform);
06998 }
06999
07000 void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
07001 {
07002 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
07003 {
07004 return;
07005 }
07006
07007 llassert (uentry_isVar (u1));
07008 llassert (uentry_isVar (u2));
07009
07010 if (u1->info->var->kind != u2->info->var->kind) {
07011 if (u1->info->var->kind == VKSEFRETPARAM) {
07012 if (u2->info->var->kind == VKRETPARAM) {
07013 voptgenerror
07014 (FLG_TYPE,
07015 message ("Function types are inconsistent. Parameter %d is "
07016 "sef parameter, but non-sef parameter in "
07017 "assigned function: %s",
07018 paramno, exprNode_unparse (e)),
07019 exprNode_loc (e));
07020 } else if (u2->info->var->kind == VKSEFPARAM) {
07021 voptgenerror
07022 (FLG_TYPE,
07023 message ("Function types are inconsistent. Parameter %d is "
07024 "returns parameter, but non-returns parameter in "
07025 "assigned function: %s",
07026 paramno, exprNode_unparse (e)),
07027 exprNode_loc (e));
07028 } else {
07029 voptgenerror
07030 (FLG_TYPE,
07031 message ("Function types are inconsistent. Parameter %d is "
07032 "sef returns parameter, but non-sef returns parameter in "
07033 "assigned function: %s",
07034 paramno, exprNode_unparse (e)),
07035 exprNode_loc (e));
07036 }
07037 } else if (u1->info->var->kind == VKRETPARAM) {
07038 voptgenerror
07039 (FLG_TYPE,
07040 message ("Function types are inconsistent. Parameter %d is "
07041 "returns parameter, but non-returns parameter in "
07042 "assigned function: %s",
07043 paramno, exprNode_unparse (e)),
07044 exprNode_loc (e));
07045 } else if (u1->info->var->kind == VKSEFPARAM) {
07046 voptgenerror
07047 (FLG_TYPE,
07048 message ("Function types are inconsistent. Parameter %d is "
07049 "sef parameter, but non-sef parameter in "
07050 "assigned function: %s",
07051 paramno, exprNode_unparse (e)),
07052 exprNode_loc (e));
07053 } else {
07054 if (u2->info->var->kind == VKSEFRETPARAM) {
07055 voptgenerror
07056 (FLG_TYPE,
07057 message ("Function types are inconsistent. Parameter %d is "
07058 "normal parameter, but sef returns parameter in "
07059 "assigned function: %s",
07060 paramno, exprNode_unparse (e)),
07061 exprNode_loc (e));
07062 } else if (u2->info->var->kind == VKSEFPARAM) {
07063 voptgenerror
07064 (FLG_TYPE,
07065 message ("Function types are inconsistent. Parameter %d is "
07066 "normal parameter, but sef parameter in "
07067 "assigned function: %s",
07068 paramno, exprNode_unparse (e)),
07069 exprNode_loc (e));
07070 } else if (u2->info->var->kind == VKRETPARAM) {
07071 voptgenerror
07072 (FLG_TYPE,
07073 message ("Function types are inconsistent. Parameter %d is "
07074 "normal parameter, but returns parameter in "
07075 "assigned function: %s",
07076 paramno, exprNode_unparse (e)),
07077 exprNode_loc (e));
07078 } else {
07079 BADBRANCH;
07080 }
07081 }
07082 }
07083
07084 if (u1->info->var->defstate != u2->info->var->defstate)
07085 {
07086 voptgenerror
07087 (FLG_TYPE,
07088 message ("Function types are inconsistent. Parameter %d is "
07089 "%s, but %s in assigned function: %s",
07090 paramno,
07091 sstate_unparse (u1->info->var->defstate),
07092 sstate_unparse (u2->info->var->defstate),
07093 exprNode_unparse (e)),
07094 exprNode_loc (e));
07095 }
07096
07097 if (u1->info->var->nullstate != u2->info->var->nullstate)
07098 {
07099 voptgenerror
07100 (FLG_TYPE,
07101 message ("Function types are inconsistent. Parameter %d is "
07102 "%s, but %s in assigned function: %s",
07103 paramno,
07104 nstate_unparse (u1->info->var->nullstate),
07105 nstate_unparse (u2->info->var->nullstate),
07106 exprNode_unparse (e)),
07107 exprNode_loc (e));
07108 }
07109
07110 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
07111 {
07112 voptgenerror
07113 (FLG_TYPE,
07114 message ("Function types are inconsistent. Parameter %d is "
07115 "%s, but %s in assigned function: %s",
07116 paramno,
07117 alkind_unparse (sRef_getAliasKind (u1->sref)),
07118 alkind_unparse (sRef_getAliasKind (u2->sref)),
07119 exprNode_unparse (e)),
07120 exprNode_loc (e));
07121 }
07122
07123 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
07124 {
07125 voptgenerror
07126 (FLG_TYPE,
07127 message ("Function types are inconsistent. Parameter %d is "
07128 "%s, but %s in assigned function: %s",
07129 paramno,
07130 exkind_unparse (sRef_getExKind (u1->sref)),
07131 exkind_unparse (sRef_getExKind (u2->sref)),
07132 exprNode_unparse (e)),
07133 exprNode_loc (e));
07134 }
07135 }
07136
07137 static void
07138 checkFunctionConformance ( uentry old,
07139 uentry unew,
07140 bool mustConform, bool completeConform)
07141 {
07142 uentryList oldParams = uentry_getParams (old);
07143 uentryList newParams = uentry_getParams (unew);
07144 ctype newType = unew->utype;
07145 ctype oldType = old->utype;
07146 ctype oldRetType = ctype_unknown;
07147 ctype newRetType = ctype_unknown;
07148
07149 if (uentry_isForward (old))
07150 {
07151 mustConform = FALSE;
07152 uentry_copyInto (old, unew);
07153 return;
07154 }
07155
07156
07157
07158
07159
07160 if (ctype_isKnown (oldType))
07161 {
07162 llassert (ctype_isFunction (oldType));
07163
07164 oldRetType = ctype_returnValue (oldType);
07165 }
07166
07167 if (ctype_isKnown (newType))
07168 {
07169 llassert (ctype_isFunction (newType));
07170
07171 newRetType = ctype_returnValue (newType);
07172 }
07173
07174 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
07175 && !ctype_matchDef (newRetType, oldRetType))
07176 {
07177 if (mustConform) returnValueError (old, unew);
07178 }
07179 else
07180 {
07181 if (ctype_isConj (newRetType))
07182 {
07183 if (ctype_isConj (oldRetType))
07184 {
07185 if (!ctype_sameAltTypes (newRetType, oldRetType))
07186 {
07187 if (optgenerror
07188 (FLG_INCONDEFS,
07189 message ("Function %q inconsistently %rdeclared to "
07190 "return alternate types %s "
07191 "(types match, but alternates are not identical, "
07192 "so checking may not be correct)",
07193 uentry_getName (unew),
07194 uentry_isDeclared (old),
07195 ctype_unparse (newRetType)),
07196 uentry_whereDeclared (unew)))
07197 {
07198 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
07199 }
07200 }
07201 }
07202 else
07203 {
07204 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
07205 }
07206 }
07207 }
07208
07209 uentry_checkStateConformance (old, unew, mustConform, completeConform);
07210
07211 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
07212 {
07213 if (exitkind_isKnown (unew->info->fcn->exitCode))
07214 {
07215 if (optgenerror
07216 (FLG_INCONDEFS,
07217 message ("Function %q inconsistently %rdeclared using %s",
07218 uentry_getName (unew),
07219 uentry_isDeclared (old),
07220 exitkind_unparse (unew->info->fcn->exitCode)),
07221 uentry_whereDeclared (unew)))
07222 {
07223 uentry_showWhereSpecified (old);
07224 }
07225 }
07226 else
07227 {
07228 unew->info->fcn->exitCode = old->info->fcn->exitCode;
07229 }
07230 }
07231
07232 if (!qual_isUnknown (unew->info->fcn->nullPred))
07233 {
07234 if (!qual_equal (old->info->fcn->nullPred, unew->info->fcn->nullPred))
07235 {
07236 if (optgenerror
07237 (FLG_INCONDEFS,
07238 message ("Function %q inconsistently %rdeclared using %s",
07239 uentry_getName (unew),
07240 uentry_isDeclared (old),
07241 qual_unparse (unew->info->fcn->nullPred)),
07242 uentry_whereDeclared (unew)))
07243 {
07244 uentry_showWhereSpecified (old);
07245 }
07246 }
07247 }
07248 else
07249 {
07250 unew->info->fcn->nullPred = old->info->fcn->nullPred;
07251 }
07252
07253 if (unew->info->fcn->specialCode != SPC_NONE)
07254 {
07255 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
07256 {
07257 if (optgenerror
07258 (FLG_INCONDEFS,
07259 message ("Function %q inconsistently %rdeclared using %s",
07260 uentry_getName (unew),
07261 uentry_isDeclared (old),
07262 specCode_unparse (unew->info->fcn->specialCode)),
07263 uentry_whereDeclared (unew)))
07264 {
07265 uentry_showWhereSpecified (old);
07266 }
07267 }
07268 }
07269 else
07270 {
07271 unew->info->fcn->specialCode = old->info->fcn->specialCode;
07272 }
07273
07274
07275
07276
07277
07278 if (!uentryList_sameObject (oldParams, newParams)
07279 && (!uentryList_isMissingParams (oldParams)))
07280 {
07281 if (!uentryList_isMissingParams (newParams))
07282 {
07283 int paramno = 0;
07284 int nparams = uentryList_size (oldParams);
07285 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
07286
07287 if (nparams != uentryList_size (newParams))
07288 {
07289 nargsError (old, unew);
07290 }
07291
07292 if (uentryList_size (newParams) < nparams)
07293 {
07294 nparams = uentryList_size (newParams);
07295 }
07296
07297 while (paramno < nparams)
07298 {
07299 uentry oldCurrent = uentryList_getN (oldParams, paramno);
07300 uentry newCurrent = uentryList_getN (newParams, paramno);
07301 ctype oldCurrentType = uentry_getType (oldCurrent);
07302 ctype newCurrentType = uentry_getType (newCurrent);
07303
07304 llassert (uentry_isValid (oldCurrent)
07305 && uentry_isValid (newCurrent));
07306
07307 if (!uentry_isElipsisMarker (oldCurrent)
07308 && !uentry_isElipsisMarker (newCurrent))
07309 {
07310 checkVarConformance (oldCurrent, newCurrent,
07311 mustConform, completeConform);
07312 }
07313
07314 if (checknames)
07315 {
07316 if (uentry_hasName (oldCurrent)
07317 && uentry_hasName (newCurrent))
07318 {
07319 cstring oldname = uentry_getName (oldCurrent);
07320 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
07321 cstring oname;
07322 cstring nname = uentry_getName (newCurrent);
07323 cstring nnamefix;
07324
07325 if (cstring_isDefined (pfx)
07326 && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
07327 {
07328 oname = cstring_suffix (oldname, cstring_length (pfx));
07329 }
07330 else
07331 {
07332 oname = oldname;
07333 }
07334
07335 if (cstring_isDefined (pfx)
07336 && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
07337 {
07338 nnamefix = cstring_suffix (nname, cstring_length (pfx));
07339 }
07340 else
07341 {
07342 nnamefix = nname;
07343 }
07344
07345 if (!cstring_equal (oname, nnamefix))
07346 {
07347 if (optgenerror
07348 (FLG_DECLPARAMMATCH,
07349 message ("Definition parameter name %s does not match "
07350 "name of corresponding parameter in "
07351 "declaration: %s",
07352 nnamefix, oname),
07353 uentry_whereLast (newCurrent)))
07354 {
07355 uentry_showWhereLastPlain (oldCurrent);
07356 }
07357 }
07358
07359 cstring_free (oldname);
07360 cstring_free (nname);
07361 }
07362 }
07363
07364 if (!ctype_match (oldCurrentType, newCurrentType))
07365 {
07366 paramTypeError (old, oldCurrent, oldCurrentType,
07367 unew, newCurrent, newCurrentType, paramno);
07368 }
07369 else
07370 {
07371 if (ctype_isMissingParamsMarker (newCurrentType)
07372 || ctype_isElips (newCurrentType)
07373 || ctype_isMissingParamsMarker (oldCurrentType)
07374 || ctype_isElips (oldCurrentType))
07375 {
07376 ;
07377 }
07378 else
07379 {
07380 if (ctype_isConj (newCurrentType))
07381 {
07382 if (ctype_isConj (oldCurrentType))
07383 {
07384 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
07385 {
07386 if (optgenerror
07387 (FLG_INCONDEFS,
07388 message ("Parameter %q inconsistently %rdeclared with "
07389 "alternate types %s "
07390 "(types match, but alternates are not identical, "
07391 "so checking may not be correct)",
07392 uentry_getName (newCurrent),
07393 uentry_isDeclared (oldCurrent),
07394 ctype_unparse (newCurrentType)),
07395 uentry_whereDeclared (unew)))
07396 {
07397 uentry_showWhereLastVal (oldCurrent,
07398 ctype_unparse (oldCurrentType));
07399 }
07400 }
07401 }
07402 else
07403 {
07404 if (optgenerror
07405 (FLG_INCONDEFS,
07406 message ("Parameter %q inconsistently %rdeclared with "
07407 "alternate types %s",
07408 uentry_getName (newCurrent),
07409 uentry_isDeclared (oldCurrent),
07410 ctype_unparse (newCurrentType)),
07411 uentry_whereDeclared (unew)))
07412 {
07413 uentry_showWhereLastVal (oldCurrent,
07414 ctype_unparse (oldCurrentType));
07415
07416 }
07417 }
07418 }
07419 else
07420 {
07421 if (ctype_isConj (oldCurrentType))
07422 {
07423 uentry_setType (newCurrent, oldCurrentType);
07424 }
07425 }
07426 }
07427 }
07428
07429 paramno++;
07430
07431
07432
07433
07434 }
07435 }
07436 }
07437
07438 if (!uentryList_isMissingParams (newParams))
07439 {
07440 if (ctype_isConj (oldRetType))
07441 {
07442 old->utype = ctype_makeFunction (oldRetType,
07443 uentryList_copy (newParams));
07444 }
07445 else
07446 {
07447 old->utype = unew->utype;
07448 }
07449 }
07450
07451 checkGlobalsConformance (old, unew, mustConform, completeConform);
07452 checkModifiesConformance (old, unew, mustConform, completeConform);
07453
07454 if (specialClauses_isDefined (unew->info->fcn->specclauses))
07455 {
07456 if (!specialClauses_isDefined (old->info->fcn->specclauses))
07457 {
07458 if (optgenerror
07459 (FLG_INCONDEFS,
07460 message ("Function %q redeclared using special clauses (can only "
07461 "be used in first declaration)",
07462 uentry_getName (unew)),
07463 uentry_whereDeclared (unew)))
07464 {
07465 uentry_showWhereLast (old);
07466 }
07467 }
07468 else
07469 {
07470 specialClauses_checkEqual (old, unew);
07471 }
07472 }
07473
07474 if (fileloc_isUndefined (old->whereDeclared))
07475 {
07476 old->whereDeclared = fileloc_copy (unew->whereDeclared);
07477 }
07478 else if (fileloc_isUndefined (unew->whereDeclared))
07479 {
07480 unew->whereDeclared = fileloc_copy (old->whereDeclared);
07481 }
07482 else
07483 {
07484
07485 }
07486 }
07487
07488 void
07489 uentry_mergeConstantValue (uentry ue, multiVal m)
07490 {
07491 multiVal uval;
07492
07493 llassert (uentry_isValid (ue));
07494 llassert (uentry_isEitherConstant (ue));
07495
07496 uval = ue->info->uconst->val;
07497
07498 if (multiVal_isDefined (uval))
07499 {
07500 if (multiVal_isDefined (m))
07501 {
07502 if (!multiVal_equiv (uval, m))
07503 {
07504 if (optgenerror
07505 (FLG_INCONDEFS,
07506 message ("%s %q defined with inconsistent value: %q",
07507 ekind_capName (ue->ukind),
07508 uentry_getName (ue),
07509 multiVal_unparse (m)),
07510 g_currentloc))
07511 {
07512 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
07513 }
07514 }
07515 }
07516 multiVal_free (m);
07517 }
07518 else
07519 {
07520 ue->info->uconst->val = m;
07521 multiVal_free (uval);
07522 }
07523 }
07524
07525 static
07526 bool checkTypeConformance ( uentry old, uentry unew,
07527 bool mustConform)
07528 {
07529 bool typeError = FALSE;
07530
07531 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
07532 {
07533 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
07534 {
07535 if (mustConform)
07536 {
07537 checkStructConformance (old, unew);
07538 }
07539 }
07540 else
07541 {
07542 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
07543 {
07544 llbug (message ("struct tags: bad types: %t / %t",
07545 old->utype, unew->utype));
07546 }
07547 }
07548 }
07549 else if (uentry_isEnumTag (old))
07550 {
07551 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
07552 {
07553 if (mustConform) checkEnumConformance (old, unew);
07554 }
07555 else
07556 {
07557 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
07558 {
07559 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
07560 ctype_unparse (unew->utype)));
07561 }
07562 }
07563 }
07564 else if (!ctype_match (old->utype, unew->utype))
07565 {
07566 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
07567 {
07568 ctype realt = ctype_realType (unew->utype);
07569
07570 if (ctype_isRealInt (realt) || ctype_isChar (realt))
07571 {
07572 unew->utype = ctype_bool;
07573 }
07574 else
07575 {
07576 if (mustConform)
07577 {
07578 typeError = optgenerror
07579 (FLG_INCONDEFS,
07580 message ("%q defined as %s", uentry_getName (old),
07581 ctype_unparse (realt)),
07582 uentry_whereDeclared (unew));
07583 }
07584 }
07585 }
07586 else
07587 {
07588 if (mustConform)
07589 {
07590 ctype oldr = ctype_realType (old->utype);
07591 ctype newr = ctype_realType (unew->utype);
07592
07593 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
07594 {
07595 checkStructConformance (old, unew);
07596 }
07597 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
07598 {
07599 checkStructConformance (old, unew);
07600 }
07601 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
07602 {
07603 checkEnumConformance (old, unew);
07604 }
07605 else if (uentry_isConstant (old)
07606 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
07607 {
07608
07609 }
07610 else
07611 {
07612 if (optgenerror
07613 (FLG_INCONDEFS,
07614 message ("%s %q %rdeclared with inconsistent type: %t",
07615 ekind_capName (unew->ukind),
07616 uentry_getName (unew),
07617 uentry_isDeclared (old),
07618 unew->utype),
07619 uentry_whereDeclared (unew)))
07620 {
07621 uentry_showWhereLast (old);
07622 typeError = TRUE;
07623 }
07624 }
07625 }
07626 }
07627 }
07628 else
07629 {
07630
07631 }
07632
07633 return typeError;
07634 }
07635
07636 static void
07637 uentry_checkDatatypeConformance ( uentry old,
07638 uentry unew,
07639 bool mustConform, bool completeConform)
07640 {
07641 if (ctype_isDefined (unew->info->datatype->type))
07642 {
07643
07644
07645
07646
07647
07648 if (ctype_isDirectBool (old->utype) &&
07649 cstring_equalLit (unew->uname, "bool"))
07650 {
07651
07652
07653
07654 unew->utype = ctype_bool;
07655 }
07656
07657 if (ctype_isUnknown (old->info->datatype->type))
07658 {
07659 old->info->datatype->type = unew->info->datatype->type;
07660 }
07661 else
07662 {
07663 if (ctype_matchDef (old->info->datatype->type,
07664 unew->info->datatype->type))
07665 {
07666 ;
07667 }
07668 else
07669 {
07670 if (optgenerror
07671 (FLG_INCONDEFS,
07672 message
07673 ("Type %q %s with inconsistent type: %t",
07674 uentry_getName (unew),
07675 uentry_reDefDecl (old, unew),
07676 unew->info->datatype->type),
07677 uentry_whereDeclared (unew)))
07678 {
07679 uentry_showWhereLastExtra
07680 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
07681 }
07682
07683 old->info->datatype->type = unew->info->datatype->type;
07684 }
07685 }
07686 }
07687
07688 if (unew->info->datatype->abs != MAYBE)
07689 {
07690 if (ynm_isOff (old->info->datatype->abs)
07691 && ynm_isOn (unew->info->datatype->abs))
07692 {
07693 if (!ctype_isDirectBool (old->utype))
07694 {
07695 if (optgenerror
07696 (FLG_INCONDEFS,
07697 message
07698 ("Datatype %q inconsistently %rdeclared as abstract type",
07699 uentry_getName (unew),
07700 uentry_isDeclared (old)),
07701 uentry_whereDeclared (unew)))
07702 {
07703 uentry_showWhereLastPlain (old);
07704 }
07705 }
07706 }
07707 else if (ynm_isOn (old->info->datatype->abs)
07708 && ynm_isOff (unew->info->datatype->abs))
07709 {
07710 if (!ctype_isDirectBool (old->utype))
07711 {
07712 if (optgenerror
07713 (FLG_INCONDEFS,
07714 message
07715 ("Datatype %q inconsistently %rdeclared as concrete type",
07716 uentry_getName (unew),
07717 uentry_isDeclared (old)),
07718 uentry_whereDeclared (unew)))
07719 {
07720 uentry_showWhereLastPlain (old);
07721 }
07722 }
07723 }
07724 else
07725 {
07726 ;
07727 }
07728 }
07729 else
07730 {
07731 if (ynm_isOn (old->info->datatype->abs))
07732 {
07733 old->sref = unew->sref;
07734 unew->info->datatype->mut = old->info->datatype->mut;
07735
07736 if (completeConform
07737 && uentry_isReallySpecified (old))
07738 {
07739 if (optgenerror
07740 (FLG_NEEDSPEC,
07741 message
07742 ("Datatype %q specified as abstract, "
07743 "but abstract annotation not used in declaration",
07744 uentry_getName (unew)),
07745 uentry_whereDeclared (unew)))
07746 {
07747 uentry_showWhereLastPlain (old);
07748 }
07749 }
07750 }
07751 }
07752
07753 unew->info->datatype->abs = old->info->datatype->abs;
07754
07755 if (ynm_isMaybe (unew->info->datatype->mut))
07756 {
07757 if (completeConform && ynm_isOff (old->info->datatype->mut)
07758 && uentry_isReallySpecified (old))
07759 {
07760 if (optgenerror
07761 (FLG_NEEDSPEC,
07762 message
07763 ("Datatype %q specified as immutable, "
07764 "but immutable annotation not used in declaration",
07765 uentry_getName (unew)),
07766 uentry_whereDeclared (unew)))
07767 {
07768 uentry_showWhereLastPlain (old);
07769 }
07770 }
07771
07772 unew->info->datatype->mut = old->info->datatype->mut;
07773 }
07774 else if (ynm_isMaybe (old->info->datatype->mut))
07775 {
07776 old->info->datatype->mut = unew->info->datatype->mut;
07777 }
07778 else
07779 {
07780 if (ynm_isOn (old->info->datatype->abs))
07781 {
07782 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
07783 {
07784 if (optgenerror
07785 (FLG_INCONDEFS,
07786 message ("Datatype %q inconsistently %rdeclared as immutable",
07787 uentry_getName (unew),
07788 uentry_isDeclared (old)),
07789 uentry_whereDeclared (unew)))
07790 {
07791 uentry_showWhereLastPlain (old);
07792 }
07793 }
07794 else
07795 {
07796 if (ynm_isOff (old->info->datatype->mut)
07797 && ynm_isOn (unew->info->datatype->mut))
07798 {
07799 if (optgenerror
07800 (FLG_INCONDEFS,
07801 message ("Datatype %q inconsistently %rdeclared as mutable",
07802 uentry_getName (unew),
07803 uentry_isDeclared (old)),
07804 uentry_whereDeclared (unew)))
07805 {
07806 uentry_showWhereLastPlain (old);
07807 }
07808 }
07809 }
07810 }
07811 old->info->datatype->mut = unew->info->datatype->mut;
07812 }
07813
07814 uentry_checkStateConformance (old, unew, mustConform, completeConform);
07815 }
07816
07817 static void
07818 uentry_checkConstantConformance ( uentry old,
07819 uentry unew,
07820 bool mustConform,
07821 bool completeConform)
07822 {
07823 multiVal oldVal = old->info->uconst->val;
07824 multiVal newVal = unew->info->uconst->val;
07825
07826 if (multiVal_isDefined (oldVal))
07827 {
07828 if (multiVal_isDefined (newVal))
07829 {
07830 if (!multiVal_equiv (oldVal, newVal))
07831 {
07832 if (mustConform
07833 && optgenerror
07834 (FLG_INCONDEFS,
07835 message ("%s %q %rdeclared with inconsistent value: %q",
07836 ekind_capName (unew->ukind),
07837 uentry_getName (unew),
07838 uentry_isDeclared (old),
07839 multiVal_unparse (newVal)),
07840 uentry_whereDeclared (unew)))
07841 {
07842 uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
07843 }
07844 }
07845
07846 unew->info->uconst->val = multiVal_copy (oldVal);
07847 multiVal_free (newVal);
07848 }
07849 else
07850 {
07851 ;
07852 }
07853 }
07854 else
07855 {
07856 old->info->uconst->val = multiVal_copy (newVal);
07857 }
07858 }
07859
07860 static void
07861 uentry_checkConformance ( uentry old,
07862 uentry unew, bool mustConform,
07863 bool completeConform)
07864 {
07865 bool typeError = FALSE;
07866 bool fcnConformance = FALSE;
07867
07868 if (!ekind_equal (unew->ukind, old->ukind))
07869 {
07870
07871
07872
07873
07874
07875 if (unew->ukind == KENUMCONST
07876 && old->ukind == KCONST)
07877 {
07878 old->ukind = KENUMCONST;
07879 goto nokinderror;
07880 }
07881
07882 if (unew->ukind == KFCN
07883 && old->ukind == KCONST
07884 && ctype_isUnknown (old->utype))
07885 {
07886
07887
07888
07889
07890 uentry_copyInto (old, unew);
07891 return;
07892 }
07893
07894 if (uentry_isExpandedMacro (old)
07895 && uentry_isEitherConstant (unew))
07896 {
07897 uentry_copyInto (old, unew);
07898 return;
07899 }
07900
07901 if (uentry_isEndIter (unew))
07902 {
07903 if (ctype_isUnknown (old->utype))
07904 {
07905 if (!uentry_isSpecified (old)
07906 && uentry_isCodeDefined (unew))
07907 {
07908 if (!fileloc_withinLines (uentry_whereDefined (old),
07909 uentry_whereDeclared (unew), 2))
07910 {
07911 voptgenerror
07912 (FLG_SYNTAX,
07913 message
07914 ("Iterator finalized name %q does not match name in "
07915 "previous iter declaration (should be end_%q). This iter "
07916 "is declared at %q",
07917 uentry_getName (unew),
07918 uentry_getName (old),
07919 fileloc_unparse (uentry_whereDefined (old))),
07920 uentry_whereDeclared (old));
07921 }
07922 }
07923
07924 uentry_copyInto (old, unew);
07925 return;
07926 }
07927 else
07928 {
07929 KindConformanceError (old, unew, mustConform);
07930 }
07931 }
07932
07933 if (uentry_isFunction (unew))
07934 {
07935 if (uentry_isVariable (old))
07936 {
07937 if (!ctype_isUnknown (old->utype))
07938 {
07939 if (ctype_isFunction (old->utype))
07940 {
07941 uentry_makeVarFunction (old);
07942 checkFunctionConformance (old, unew, mustConform,
07943 completeConform);
07944 fcnConformance = TRUE;
07945 }
07946 else
07947 {
07948 KindConformanceError (old, unew, mustConform);
07949 }
07950 }
07951 else
07952 {
07953 if (uentry_isExpandedMacro (old))
07954 {
07955 if (fileloc_isUndefined (unew->whereDefined))
07956 {
07957 unew->whereDefined = fileloc_update (unew->whereDefined,
07958 old->whereDefined);
07959 }
07960
07961 uentry_copyInto (old, unew);
07962 old->used = unew->used = TRUE;
07963 return;
07964 }
07965 else
07966 {
07967
07968 old->utype = unew->utype;
07969 uentry_makeVarFunction (old);
07970 checkFunctionConformance (old, unew, FALSE, FALSE);
07971 fcnConformance = TRUE;
07972 }
07973 }
07974 }
07975 else
07976 {
07977 KindConformanceError (old, unew, mustConform);
07978 }
07979 }
07980 else if (uentry_isFunction (old) && uentry_isVariable (unew))
07981 {
07982 if (!ctype_isUnknown (unew->utype))
07983 {
07984 if (ctype_isFunction (unew->utype))
07985 {
07986 uentry_makeVarFunction (unew);
07987 checkFunctionConformance (old, unew, mustConform, completeConform);
07988 fcnConformance = TRUE;
07989 }
07990 else
07991 {
07992 KindConformanceError (old, unew, mustConform);
07993 }
07994 }
07995 else
07996 {
07997 KindConformanceError (old, unew, mustConform);
07998 }
07999 }
08000 else
08001 {
08002 KindConformanceError (old, unew, mustConform);
08003 }
08004 }
08005 else
08006 {
08007
08008
08009
08010
08011
08012 if (uentry_isFunction (old))
08013 {
08014 checkFunctionConformance (old, unew, mustConform, completeConform);
08015 fcnConformance = TRUE;
08016 }
08017 else
08018 {
08019 if (!ctype_isUndefined (old->utype))
08020 {
08021 typeError = checkTypeConformance (old, unew, mustConform);
08022 }
08023 }
08024 }
08025
08026 nokinderror:
08027
08028 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
08029 {
08030 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
08031 }
08032
08033 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
08034 {
08035 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
08036 }
08037
08038 if (uentry_isVariable (old) && uentry_isVariable (unew))
08039 {
08040 if (!typeError &&
08041 !ctype_matchDef (old->utype, unew->utype))
08042 {
08043 if (optgenerror
08044 (FLG_INCONDEFS,
08045 message
08046 ("Variable %q %s with inconsistent type (arrays and pointers are "
08047 "not identical in variable declarations): %t",
08048 uentry_getName (unew),
08049 uentry_reDefDecl (old, unew),
08050 unew->utype),
08051 uentry_whereDeclared (unew)))
08052 {
08053 uentry_showWhereLast (old);
08054
08055
08056
08057
08058
08059 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
08060 {
08061 old->whereDefined = fileloc_update (old->whereDefined,
08062 fileloc_undefined);
08063 }
08064
08065 typeError = TRUE;
08066 }
08067 }
08068
08069 checkVarConformance (old, unew, mustConform, completeConform);
08070 }
08071
08072 if (fcnConformance)
08073 {
08074
08075 }
08076 else
08077 {
08078 if (ctype_isConj (old->utype))
08079 {
08080 if (ctype_isConj (unew->utype))
08081 {
08082 if (!ctype_sameAltTypes (old->utype, unew->utype))
08083 {
08084 if (optgenerror
08085 (FLG_INCONDEFS,
08086 message ("%s %q inconsistently %rdeclared with "
08087 "alternate types %s "
08088 "(types match, but alternates are not identical, "
08089 "so checking may not be correct)",
08090 ekind_capName (uentry_getKind (old)),
08091 uentry_getName (unew),
08092 uentry_isDeclared (old),
08093 ctype_unparse (unew->utype)),
08094 uentry_whereDeclared (unew)))
08095 {
08096 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
08097 }
08098 else
08099 {
08100 old->utype = unew->utype;
08101 }
08102 }
08103 }
08104 }
08105 else
08106 {
08107 if (ctype_isUnknown (old->utype))
08108 {
08109 old->utype = unew->utype;
08110 }
08111 }
08112 }
08113
08114 if (unew->ukind == old->ukind)
08115 {
08116 sfree (unew->info);
08117 unew->info = uinfo_copy (old->info, old->ukind);
08118 }
08119
08120 sRef_storeState (old->sref);
08121 sRef_storeState (unew->sref);
08122 }
08123
08124
08125
08126
08127
08128 void
08129 uentry_mergeEntries (uentry spec, uentry def)
08130 {
08131 llassert (uentry_isValid (spec));
08132 llassert (uentry_isValid (def));
08133 llassert (cstring_equal (spec->uname, def->uname));
08134
08135 uentry_checkConformance (spec, def, TRUE,
08136 context_getFlag (FLG_NEEDSPEC));
08137
08138
08139
08140
08141
08142
08143
08144 uentry_setDefined (spec, uentry_whereDefined (def));
08145 uentry_setDeclared (spec, uentry_whereDeclared (def));
08146
08147 if (uentry_isStatic (def))
08148 {
08149 if (optgenerror
08150 (FLG_INCONDEFS,
08151 message ("%s %q specified, but declared as static",
08152 ekind_capName (def->ukind),
08153 uentry_getName (def)),
08154 uentry_whereDeclared (def)))
08155 {
08156 uentry_showWhereSpecified (spec);
08157 }
08158 }
08159 else
08160 {
08161 spec->storageclass = def->storageclass;
08162 }
08163
08164 sRef_storeState (spec->sref);
08165
08166 spec->used = def->used || spec->used;
08167 spec->hasNameError |= def->hasNameError;
08168
08169 uentry_free (def);
08170
08171 if (!spec->hasNameError)
08172 {
08173 uentry_checkName (spec);
08174 }
08175 else
08176 {
08177 ;
08178 }
08179 }
08180
08181
08182
08183
08184
08185
08186
08187 void
08188 uentry_clearDecl (void)
08189 {
08190 posRedeclared = uentry_undefined;
08191 fileloc_free (posLoc);
08192 posLoc = fileloc_undefined;
08193 }
08194
08195 void
08196 uentry_checkDecl (void)
08197 {
08198 if (uentry_isValid (posRedeclared))
08199 {
08200 llassert (fileloc_isDefined (posLoc));
08201
08202 if (uentry_isCodeDefined (posRedeclared))
08203 {
08204 if (optgenerror (FLG_REDECL,
08205 message ("%s %q declared after definition",
08206 ekind_capName (posRedeclared->ukind),
08207 uentry_getName (posRedeclared)),
08208 posLoc))
08209 {
08210 llgenindentmsg (message ("Definition of %q",
08211 uentry_getName (posRedeclared)),
08212 posRedeclared->whereDeclared);
08213 }
08214 }
08215 else
08216 {
08217 if (optgenerror (FLG_REDECL,
08218 message ("%s %q declared more than once",
08219 ekind_capName (posRedeclared->ukind),
08220 uentry_getName (posRedeclared)),
08221 posLoc))
08222 {
08223 llgenindentmsg (message ("Previous declaration of %q",
08224 uentry_getName (posRedeclared)),
08225 posRedeclared->whereDeclared);
08226 }
08227 }
08228 }
08229
08230 fileloc_free (posLoc);
08231 posLoc = fileloc_undefined;
08232 posRedeclared = uentry_undefined;
08233 }
08234
08235
08236
08237
08238
08239
08240 void
08241 uentry_mergeDefinition (uentry old, uentry unew)
08242 {
08243 fileloc olddef = uentry_whereDeclared (old);
08244 fileloc unewdef = uentry_whereDeclared (unew);
08245 bool mustConform;
08246 bool wasForward;
08247
08248 if (uentry_isExtern (unew))
08249 {
08250 uentry_setUsed (old, unewdef);
08251 }
08252
08253 wasForward =
08254 fileloc_isUndefined (olddef)
08255 && fileloc_isDefined (uentry_whereDefined (old))
08256 && !uentry_isExpandedMacro (old);
08257
08258 if (!context_getFlag (FLG_INCONDEFSLIB)
08259 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
08260 {
08261 mustConform = FALSE;
08262 }
08263 else
08264 {
08265 mustConform = TRUE;
08266 }
08267
08268 llassert (uentry_isValid (old));
08269 llassert (uentry_isValid (unew));
08270 llassert (cstring_equal (old->uname, unew->uname));
08271
08272
08273
08274
08275
08276 if (uentry_isStatic (old))
08277 {
08278 if (!(uentry_isStatic (unew)))
08279 {
08280 if (optgenerror
08281 (FLG_SHADOW,
08282 message ("%s %q shadows static declaration",
08283 ekind_capName (unew->ukind),
08284 uentry_getName (unew)),
08285 unewdef))
08286 {
08287 uentry_showWhereLast (old);
08288 }
08289 }
08290 else
08291 {
08292 uentry_setDeclDef (old, unewdef);
08293 }
08294 }
08295 else if (uentry_isStatic (unew))
08296 {
08297 uentry_setDeclDef (old, unewdef);
08298 }
08299 else if (uentry_isExtern (old))
08300 {
08301 uentry_setDeclared (old, unewdef);
08302 }
08303 else
08304 {
08305 if (!uentry_isExtern (unew) && !uentry_isForward (old)
08306 && !fileloc_equal (olddef, unewdef)
08307 && !fileloc_isUndefined (olddef)
08308 && !fileloc_isUndefined (unewdef)
08309 && !fileloc_isBuiltin (olddef)
08310 && !fileloc_isBuiltin (unewdef)
08311 && !uentry_isYield (old)
08312 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
08313 {
08314 if (uentry_isVariable (old) || uentry_isVariable (unew))
08315 {
08316 ;
08317 }
08318 else
08319 {
08320 if (fileloc_isDefined (uentry_whereDefined (old)))
08321 {
08322 if (optgenerror
08323 (FLG_REDEF,
08324 message ("%s %q defined more than once",
08325 ekind_capName (unew->ukind),
08326 uentry_getName (unew)),
08327 uentry_whereLast (unew)))
08328 {
08329 llgenindentmsg
08330 (message ("Previous definition of %q",
08331 uentry_getName (old)),
08332 uentry_whereLast (old));
08333 }
08334
08335
08336
08337
08338
08339
08340
08341 }
08342 }
08343 }
08344 else
08345 {
08346 if (fileloc_isLib (olddef)
08347 || fileloc_isUndefined (olddef)
08348 || fileloc_isImport (olddef))
08349 {
08350 if (uentry_isExtern (unew))
08351 {
08352 if (uentry_isExtern (old)
08353 || (fileloc_isDefined (uentry_whereDeclared (old))
08354 && (!fileloc_equal (uentry_whereDeclared (old),
08355 uentry_whereDefined (old)))))
08356 {
08357 if (optgenerror
08358 (FLG_REDECL,
08359 message ("%s %q declared more than once",
08360 ekind_capName (unew->ukind),
08361 uentry_getName (unew)),
08362 unew->whereDeclared))
08363 {
08364 llgenindentmsg
08365 (message ("Previous declaration of %q",
08366 uentry_getName (old)),
08367 old->whereDeclared);
08368 }
08369 }
08370
08371 uentry_setExtern (old);
08372 }
08373 else
08374 {
08375 uentry_setDefined (old, unewdef);
08376 }
08377 }
08378 }
08379 }
08380
08381 uentry_checkConformance (old, unew, mustConform, FALSE);
08382
08383 old->used = old->used || unew->used;
08384 old->uses = filelocList_append (old->uses, unew->uses);
08385 unew->uses = filelocList_undefined;
08386
08387 sRef_storeState (old->sref);
08388 sRef_storeState (unew->sref);
08389
08390 if (wasForward)
08391 {
08392 old->whereDefined = fileloc_update (old->whereDefined,
08393 fileloc_undefined);
08394 }
08395
08396
08397
08398
08399
08400
08401 if (fileloc_isUser (old->whereDeclared)
08402 && fileloc_isUser (unew->whereDeclared)
08403 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
08404 && !fileloc_isDefined (unew->whereDefined))
08405 {
08406 if (uentry_isFunction (old))
08407 {
08408 posRedeclared = old;
08409 posLoc = fileloc_update (posLoc, unew->whereDeclared);
08410 }
08411 else
08412 {
08413 if (optgenerror (FLG_REDECL,
08414 message ("%s %q declared more than once",
08415 ekind_capName (unew->ukind),
08416 uentry_getName (unew)),
08417 unew->whereDeclared))
08418 {
08419 llgenindentmsg (message ("Previous declaration of %q",
08420 uentry_getName (old)),
08421 old->whereDeclared);
08422 }
08423 }
08424 }
08425
08426 if (fileloc_isUndefined (old->whereDefined))
08427 {
08428 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
08429 }
08430 else
08431 {
08432 if (!context_processingMacros ()
08433 && fileloc_isUser (old->whereDefined)
08434 && fileloc_isUser (unew->whereDefined)
08435 && !fileloc_equal (old->whereDefined, unew->whereDefined))
08436 {
08437 if (uentry_isVariable (unew) || uentry_isFunction (unew))
08438 {
08439 if (uentry_isVariable (unew)
08440 && uentry_isExtern (unew))
08441 {
08442 if (optgenerror (FLG_REDECL,
08443 message ("%s %q declared after definition",
08444 ekind_capName (unew->ukind),
08445 uentry_getName (unew)),
08446 unew->whereDeclared))
08447 {
08448 llgenindentmsg (message ("Definition of %q",
08449 uentry_getName (old)),
08450 old->whereDefined);
08451 }
08452 }
08453 else
08454 {
08455 if (optgenerror (FLG_REDEF,
08456 message ("%s %q redefined",
08457 ekind_capName (unew->ukind),
08458 uentry_getName (unew)),
08459 unew->whereDefined))
08460 {
08461 llgenindentmsg (message ("Previous definition of %q",
08462 uentry_getName (old)),
08463 old->whereDefined);
08464 }
08465 }
08466 }
08467 }
08468 }
08469
08470 if (uentry_isExternal (unew))
08471 {
08472 old->whereDefined = fileloc_createExternal ();
08473 }
08474
08475 if (unew->hasNameError)
08476 {
08477 old->hasNameError = TRUE;
08478 }
08479
08480 uentry_free (unew);
08481
08482 if (!old->hasNameError)
08483 {
08484 uentry_checkName (old);
08485 }
08486
08487 llassert (!ctype_isUndefined (old->utype));
08488 }
08489
08490 void
08491 uentry_copyState (uentry res, uentry other)
08492 {
08493 llassert (uentry_isValid (res));
08494 llassert (uentry_isValid (other));
08495
08496 res->used = other->used;
08497
08498 res->info->var->kind = other->info->var->kind;
08499 res->info->var->defstate = other->info->var->defstate;
08500 res->info->var->nullstate = other->info->var->nullstate;
08501 res->info->var->checked = other->info->var->checked;
08502
08503 sRef_copyState (res->sref, other->sref);
08504 }
08505
08506 bool
08507 uentry_sameKind (uentry u1, uentry u2)
08508 {
08509 if (uentry_isValid (u1) && uentry_isValid (u2))
08510 {
08511 if (uentry_isVar (u1) && uentry_isVar (u2))
08512 {
08513 ctype c1 = u1->utype;
08514 ctype c2 = u2->utype;
08515
08516 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
08517
08518
08519
08520
08521
08522 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
08523 }
08524 else
08525 {
08526 return ((u1->ukind == u2->ukind));
08527 }
08528 }
08529
08530 return FALSE;
08531 }
08532
08533 static void uentry_copyInto ( uentry unew, uentry old)
08534 {
08535 llassert (uentry_isValid (unew));
08536 llassert (uentry_isValid (old));
08537
08538 unew->ukind = old->ukind;
08539 unew->uname = cstring_copy (old->uname);
08540 unew->utype = old->utype;
08541
08542 unew->whereSpecified = fileloc_copy (old->whereSpecified);
08543 unew->whereDefined = fileloc_copy (old->whereDefined);
08544 unew->whereDeclared = fileloc_copy (old->whereDeclared);
08545
08546 unew->sref = sRef_saveCopy (old->sref);
08547 unew->used = old->used;
08548 unew->lset = FALSE;
08549 unew->isPrivate = old->isPrivate;
08550 unew->hasNameError = old->hasNameError;
08551 unew->uses = filelocList_undefined;
08552
08553 unew->storageclass = old->storageclass;
08554 unew->info = uinfo_copy (old->info, old->ukind);
08555 }
08556
08557
08558 uentry
08559 uentry_copy (uentry e)
08560 {
08561 if (uentry_isValid (e))
08562 {
08563 uentry enew = uentry_alloc ();
08564 DPRINTF (("copy: %s", uentry_unparseFull (e)));
08565 uentry_copyInto (enew, e);
08566 DPRINTF (("Here we are..."));
08567 DPRINTF (("original: %s", uentry_unparseFull (e)));
08568 DPRINTF (("copy: %s", uentry_unparse (enew)));
08569 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
08570 return enew;
08571 }
08572 else
08573 {
08574 return uentry_undefined;
08575 }
08576 }
08577
08578 void
08579 uentry_setState (uentry res, uentry other)
08580 {
08581 llassert (uentry_isValid (res));
08582 llassert (uentry_isValid (other));
08583
08584 llassert (res->ukind == other->ukind);
08585 llassert (res->ukind == KVAR);
08586
08587 res->sref = sRef_saveCopy (other->sref);
08588 res->used = other->used;
08589 filelocList_free (res->uses);
08590 res->uses = other->uses;
08591 other->uses = filelocList_undefined;
08592 res->lset = other->lset;
08593 }
08594
08595 void
08596 uentry_mergeUses (uentry res, uentry other)
08597 {
08598 llassert (uentry_isValid (res));
08599 llassert (uentry_isValid (other));
08600
08601 res->used = other->used || res->used;
08602 res->lset = other->lset || res->lset;
08603 res->uses = filelocList_append (res->uses, other->uses);
08604 other->uses = filelocList_undefined;
08605 }
08606
08607
08608
08609
08610
08611
08612
08613
08614
08615
08616
08617
08618
08619
08620
08621
08622
08623
08624
08625
08626
08627
08628 static void
08629 branchStateError ( uentry res, uentry other,
08630 bool flip, clause cl, fileloc loc)
08631 {
08632 if (optgenerror
08633 (FLG_BRANCHSTATE,
08634 message ("%s %q is %s %s, but %s %s.",
08635 ekind_capName (res->ukind), uentry_getName (res),
08636 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
08637 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
08638 loc))
08639 {
08640 if (sRef_isDead (res->sref))
08641 {
08642 sRef_showStateInfo (res->sref);
08643 }
08644 else if (sRef_isKept (res->sref))
08645 {
08646 sRef_showAliasInfo (res->sref);
08647 }
08648 else
08649 {
08650 sRef_showAliasInfo (res->sref);
08651 sRef_showAliasInfo (other->sref);
08652 }
08653
08654 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
08655 }
08656 }
08657
08658 static bool incompatibleStates (sRef rs, sRef os)
08659 {
08660 alkind rk = sRef_getAliasKind (rs);
08661 alkind ok = sRef_getAliasKind (os);
08662
08663 if (alkind_isError (rk) || alkind_isError (ok))
08664 {
08665 return FALSE;
08666 }
08667 else
08668 {
08669 return ((sRef_isDead (rs)
08670 || (alkind_isKept (rk) && !alkind_isKept (ok))
08671 || (alkind_isDependent (rk)
08672 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
08673 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
08674 }
08675 }
08676
08677 static void
08678 branchStateAltError ( uentry res,
08679 uentry other, bool flip,
08680 clause cl, fileloc loc)
08681 {
08682 if (optgenerror
08683 (FLG_BRANCHSTATE,
08684 message ("%s %q is %s %s, but %s %s.",
08685 ekind_capName (res->ukind), uentry_getName (res),
08686 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
08687 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
08688 loc))
08689 {
08690 if (sRef_isDead (other->sref))
08691 {
08692 sRef_showStateInfo (other->sref);
08693 }
08694 else
08695 {
08696 sRef_showAliasInfo (other->sref);
08697 }
08698
08699 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
08700 sRef_setDefinedComplete (res->sref, fileloc_undefined);
08701
08702 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
08703 sRef_setDefinedComplete (other->sref, fileloc_undefined);
08704 }
08705 }
08706
08707 static bool notNull (sRef sr, bool flip)
08708 {
08709 return (!sRef_definitelyNull (sr)
08710 && !(sRef_isKept (sr))
08711 && !(sRef_isDependent (sr))
08712 && !(flip ? usymtab_isProbableDeepNull (sr)
08713 : usymtab_isAltProbablyDeepNull (sr)));
08714 }
08715
08716 void
08717 uentry_mergeState (uentry res, uentry other, fileloc loc,
08718 bool mustReturn, bool flip, bool opt,
08719 clause cl)
08720 {
08721 llassert (uentry_isValid (res));
08722 llassert (uentry_isValid (other));
08723
08724 llassert (res->ukind == other->ukind);
08725 llassert (res->ukind == KVAR);
08726
08727 DPRINTF (("Merge state: %s / %s",
08728 uentry_unparse (res),
08729 uentry_unparse (other)));
08730
08731 if (sRef_isValid (res->sref))
08732 {
08733 if (!mustReturn)
08734 {
08735 if (incompatibleStates (res->sref, other->sref))
08736 {
08737 if (sRef_isThroughArrayFetch (res->sref)
08738 && !context_getFlag (FLG_STRICTBRANCHSTATE))
08739 {
08740 if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
08741 {
08742 sRef_maybeKill (res->sref, loc);
08743 }
08744 else if (sRef_isPossiblyDead (other->sref))
08745 {
08746 sRef_maybeKill (res->sref, loc);
08747 }
08748 else
08749 {
08750 ;
08751 }
08752 }
08753 else
08754 {
08755 if (notNull (other->sref, flip))
08756 {
08757 if (sRef_isLocalParamVar (res->sref)
08758 && (sRef_isLocalState (other->sref)
08759 || sRef_isDependent (other->sref)))
08760 {
08761 if (sRef_isDependent (res->sref))
08762 {
08763 sRef_setDependent (other->sref, loc);
08764 }
08765 else
08766 {
08767 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
08768 }
08769 }
08770 else
08771 {
08772 branchStateError (res, other, flip, cl, loc);
08773 }
08774 }
08775 }
08776
08777 if (sRef_isKept (res->sref))
08778 {
08779 sRef_setKept (other->sref, loc);
08780 }
08781 }
08782 else
08783 {
08784 if (incompatibleStates (other->sref, res->sref))
08785 {
08786 if (notNull (res->sref, !flip))
08787 {
08788 if (sRef_isLocalParamVar (res->sref)
08789 && (sRef_isDependent (res->sref)
08790 || sRef_isLocalState (res->sref)))
08791 {
08792 if (sRef_isDependent (other->sref))
08793 {
08794 sRef_setDependent (res->sref, loc);
08795 }
08796 else
08797 {
08798 sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
08799 }
08800 }
08801 else
08802 {
08803 if (sRef_isParam (other->sref))
08804 {
08805
08806
08807
08808
08809
08810
08811
08812 uentry uvar = usymtab_lookupSafe (other->uname);
08813
08814 if (uentry_isValid (uvar)
08815 && ((sRef_isDead (other->sref)
08816 && sRef_isOnly (uvar->sref))
08817 || (sRef_isDependent (other->sref)
08818 && sRef_isOwned (uvar->sref))))
08819 {
08820
08821 }
08822 else
08823 {
08824 branchStateAltError (res, other,
08825 flip, cl, loc);
08826 }
08827 }
08828 else
08829 {
08830 branchStateAltError (res, other,
08831 flip, cl, loc);
08832 }
08833 }
08834 }
08835 }
08836
08837 if (sRef_isKept (other->sref))
08838 {
08839 sRef_setKept (res->sref, loc);
08840 }
08841 }
08842
08843 if (opt)
08844 {
08845 DPRINTF (("Merge opt..."));
08846 sRef_mergeOptState (res->sref, other->sref, cl, loc);
08847 DPRINTF (("Done!"));
08848 }
08849 else
08850 {
08851 sRef_mergeState (res->sref, other->sref, cl, loc);
08852 }
08853 }
08854 else
08855 {
08856 if (sRef_isModified (other->sref))
08857 {
08858 sRef_setModified (res->sref);
08859 }
08860 }
08861
08862 if (cl == DOWHILECLAUSE)
08863 {
08864 res->used = other->used || res->used;
08865 res->lset = other->lset || res->lset;
08866 res->uses = filelocList_append (res->uses, other->uses);
08867 other->uses = filelocList_undefined;
08868 }
08869 else
08870 {
08871 if (sRef_isMacroParamRef (res->sref)
08872 && !uentry_isSefParam (other)
08873 && !uentry_isSefParam (res))
08874 {
08875 bool hasError = FALSE;
08876
08877 if (bool_equal (res->used, other->used))
08878 {
08879 res->used = other->used;
08880 }
08881 else
08882 {
08883 if (other->used && !flip)
08884 {
08885 hasError =
08886 optgenerror
08887 (FLG_MACROPARAMS,
08888 message ("Macro parameter %q used in true clause, "
08889 "but not in false clause",
08890 uentry_getName (res)),
08891 uentry_whereDeclared (res));
08892 }
08893 else
08894 {
08895 hasError =
08896 optgenerror
08897 (FLG_MACROPARAMS,
08898 message ("Macro parameter %q used in false clause, "
08899 "but not in true clause",
08900 uentry_getName (res)),
08901 uentry_whereDeclared (res));
08902 }
08903 res->used = TRUE;
08904
08905 if (hasError)
08906 {
08907
08908 res->info->var->kind = VKREFSEFPARAM;
08909 }
08910 }
08911 }
08912 else
08913 {
08914 res->used = other->used || res->used;
08915 res->lset = other->lset || res->lset;
08916 res->uses = filelocList_append (res->uses, other->uses);
08917 other->uses = filelocList_undefined;
08918 }
08919 }
08920 }
08921 }
08922
08923 void uentry_setUsed (uentry e, fileloc loc)
08924 {
08925 static bool firstTime = TRUE;
08926 static bool showUses = FALSE;
08927 static bool exportLocal = FALSE;
08928
08929 if (firstTime)
08930 {
08931
08932
08933 showUses = context_getFlag (FLG_SHOWUSES);
08934 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
08935
08936 firstTime = FALSE;
08937 }
08938
08939 if (uentry_isValid (e))
08940 {
08941 int dp;
08942
08943 if (sRef_isMacroParamRef (e->sref))
08944 {
08945 if (uentry_isYield (e) || uentry_isSefParam (e))
08946 {
08947 ;
08948 }
08949 else
08950 {
08951 if (context_inConditional ())
08952 {
08953 if (optgenerror
08954 (FLG_MACROPARAMS,
08955 message ("Macro parameter %q used in conditionally "
08956 "executed code (may or may not be "
08957 "evaluated exactly once)",
08958 uentry_getName (e)),
08959 loc))
08960 {
08961 e->info->var->kind = VKREFSEFPARAM;
08962 }
08963 }
08964 else
08965 {
08966 if ((e)->used)
08967 {
08968 if (optgenerror
08969 (FLG_MACROPARAMS,
08970 message ("Macro parameter %q used more than once",
08971 uentry_getName (e)),
08972 uentry_whereDeclared (e)))
08973 {
08974 e->info->var->kind = VKREFSEFPARAM;
08975 }
08976 }
08977 }
08978 }
08979 }
08980
08981 if ((dp = uentry_directParamNo (e)) >= 0)
08982 {
08983 uentry_setUsed (usymtab_getParam (dp), loc);
08984 }
08985
08986 e->used = TRUE;
08987
08988 if (!sRef_isLocalVar (e->sref))
08989 {
08990 if (showUses)
08991 {
08992 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
08993 }
08994 else
08995 {
08996 if (exportLocal)
08997 {
08998 if (context_inMacro ())
08999 {
09000 e->uses = filelocList_addUndefined (e->uses);
09001 }
09002 else
09003 {
09004 e->uses = filelocList_addDifferentFile
09005 (e->uses,
09006 uentry_whereDeclared (e),
09007 loc);
09008 }
09009 }
09010 }
09011 }
09012 }
09013 }
09014
09015 bool uentry_isReturned (uentry u)
09016 {
09017 return (uentry_isValid (u) && uentry_isVar (u)
09018 && (u->info->var->kind == VKRETPARAM
09019 || u->info->var->kind == VKSEFRETPARAM));
09020 }
09021
09022 sRef uentry_returnedRef (uentry u, exprNodeList args)
09023 {
09024 llassert (uentry_isRealFunction (u));
09025
09026 if (ctype_isFunction (u->utype)
09027 && sRef_isStateSpecial (uentry_getSref (u)))
09028 {
09029 specialClauses clauses = uentry_getSpecialClauses (u);
09030 sRef res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
09031
09032 sRef_setAllocated (res, g_currentloc);
09033
09034 specialClauses_postElements (clauses, cl)
09035 {
09036 sRefSet refs = specialClause_getRefs (cl);
09037 sRefMod modf = specialClause_getEffectFunction (cl);
09038
09039 sRefSet_elements (refs, el)
09040 {
09041 sRef base = sRef_getRootBase (el);
09042
09043 if (sRef_isResult (base))
09044 {
09045 if (modf != NULL)
09046 {
09047 sRef sr = sRef_fixBase (el, res);
09048 modf (sr, g_currentloc);
09049 }
09050 }
09051 else
09052 {
09053 ;
09054 }
09055 } end_sRefSet_elements ;
09056
09057 } end_specialClauses_postElements ;
09058
09059 return res;
09060 }
09061 else
09062 {
09063 uentryList params;
09064 alkind ak;
09065 sRefSet prefs = sRefSet_new ();
09066 sRef res = sRef_undefined;
09067 int paramno = 0;
09068
09069 params = uentry_getParams (u);
09070
09071 uentryList_elements (params, current)
09072 {
09073 if (uentry_isReturned (current))
09074 {
09075 if (exprNodeList_size (args) >= paramno)
09076 {
09077 exprNode ecur = exprNodeList_nth (args, paramno);
09078 sRef tref = exprNode_getSref (ecur);
09079
09080 if (sRef_isValid (tref))
09081 {
09082 sRef tcref = sRef_copy (tref);
09083
09084 if (sRef_isDead (tcref))
09085 {
09086 sRef_setDefined (tcref, g_currentloc);
09087 sRef_setOnly (tcref, g_currentloc);
09088 }
09089
09090 if (sRef_isRefCounted (tcref))
09091 {
09092
09093 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
09094 }
09095
09096 sRef_makeSafe (tcref);
09097
09098 prefs = sRefSet_insert (prefs, tcref);
09099 }
09100 }
09101 }
09102
09103 paramno++;
09104 } end_uentryList_elements ;
09105
09106 if (sRefSet_size (prefs) > 0)
09107 {
09108 nstate n = sRef_getNullState (u->sref);
09109
09110 if (sRefSet_size (prefs) == 1)
09111 {
09112 res = sRefSet_choose (prefs);
09113 }
09114 else
09115 {
09116 res = sRefSet_mergeIntoOne (prefs);
09117 }
09118
09119 if (nstate_isKnown (n))
09120 {
09121 sRef_setNullState (res, n, g_currentloc);
09122 }
09123 }
09124 else
09125 {
09126 if (ctype_isFunction (u->utype))
09127 {
09128 res = sRef_makeNew (ctype_returnValue (u->utype), u->sref, u->uname);
09129 }
09130 else
09131 {
09132 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
09133 }
09134
09135 if (sRef_isRefCounted (res))
09136 {
09137 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
09138 }
09139 }
09140
09141 if (sRef_getNullState (res) == NS_ABSNULL)
09142 {
09143 ctype ct = ctype_realType (u->utype);
09144
09145 if (ctype_isAbstract (ct))
09146 {
09147 sRef_setNotNull (res, g_currentloc);
09148 }
09149 else
09150 {
09151 if (ctype_isUser (ct))
09152 {
09153 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
09154 }
09155 else
09156 {
09157 sRef_setNotNull (res, g_currentloc);
09158 }
09159 }
09160 }
09161
09162 if (sRef_isRefCounted (res))
09163 {
09164 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
09165 }
09166 else if (sRef_isKillRef (res))
09167 {
09168 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
09169 }
09170 else
09171 {
09172 ;
09173 }
09174
09175 ak = sRef_getAliasKind (res);
09176
09177 if (alkind_isImplicit (ak))
09178 {
09179 sRef_setAliasKind (res,
09180 alkind_fixImplicit (ak),
09181 g_currentloc);
09182 }
09183
09184 sRefSet_free (prefs);
09185
09186 return res;
09187 }
09188 }
09189
09190 static bool uentry_isRefCounted (uentry ue)
09191 {
09192 ctype ct = uentry_getType (ue);
09193
09194 if (ctype_isFunction (ct))
09195 {
09196 return (ctype_isRefCounted (ctype_returnValue (ct)));
09197 }
09198 else
09199 {
09200 return (ctype_isRefCounted (ct));
09201 }
09202 }
09203
09204
09205
09206
09207
09208
09209 void uentry_checkYieldParam (uentry old, uentry unew)
09210 {
09211 cstring name;
09212
09213 llassert (uentry_isVariable (old));
09214 llassert (uentry_isVariable (unew));
09215
09216 unew->info->var->kind = VKYIELDPARAM;
09217 (void) checkTypeConformance (old, unew, TRUE);
09218 checkVarConformance (old, unew, TRUE, FALSE);
09219
09220
09221
09222 name = uentry_getName (unew);
09223 cstring_free (unew->uname);
09224 unew->uname = name;
09225 unew->info->var->kind = VKREFYIELDPARAM;
09226
09227 uentry_setUsed (old, fileloc_undefined);
09228 uentry_setUsed (unew, fileloc_undefined);
09229 }
09230
09231 cstring
09232 uentry_ekindName (uentry ue)
09233 {
09234 if (uentry_isValid (ue))
09235 {
09236 switch (ue->ukind)
09237 {
09238 case KINVALID:
09239 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
09240 case KDATATYPE:
09241 return cstring_makeLiteralTemp ("Datatype");
09242 case KENUMCONST:
09243 return cstring_makeLiteralTemp ("Enum member");
09244 case KCONST:
09245 return cstring_makeLiteralTemp ("Constant");
09246 case KVAR:
09247 if (uentry_isParam (ue))
09248 {
09249 return cstring_makeLiteralTemp ("Parameter");
09250 }
09251 else if (uentry_isExpandedMacro (ue))
09252 {
09253 return cstring_makeLiteralTemp ("Expanded macro");
09254 }
09255 else
09256 {
09257 return cstring_makeLiteralTemp ("Variable");
09258 }
09259 case KFCN:
09260 return cstring_makeLiteralTemp ("Function");
09261 case KITER:
09262 return cstring_makeLiteralTemp ("Iterator");
09263 case KENDITER:
09264 return cstring_makeLiteralTemp ("Iterator finalizer");
09265 case KSTRUCTTAG:
09266 return cstring_makeLiteralTemp ("Struct tag");
09267 case KUNIONTAG:
09268 return cstring_makeLiteralTemp ("Union tag");
09269 case KENUMTAG:
09270 return cstring_makeLiteralTemp ("Enum tag");
09271 case KELIPSMARKER:
09272 return cstring_makeLiteralTemp ("Optional parameters");
09273 }
09274 }
09275 else
09276 {
09277 return cstring_makeLiteralTemp ("<Undefined>");
09278 }
09279
09280 BADEXIT;
09281 }
09282
09283 void uentry_setHasNameError (uentry ue)
09284 {
09285 llassert (uentry_isValid (ue));
09286
09287 ue->hasNameError = TRUE;
09288 }
09289
09290 void uentry_checkName (uentry ue)
09291 {
09292 if (uentry_isValid (ue)
09293 && !uentry_isElipsisMarker (ue)
09294 && context_getFlag (FLG_NAMECHECKS)
09295 && !ue->hasNameError
09296 && !uentry_isEndIter (ue)
09297 && !fileloc_isBuiltin (uentry_whereLast (ue))
09298 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
09299 {
09300
09301 if (uentry_isPriv (ue))
09302 {
09303 ;
09304 }
09305 else if (fileloc_isExternal (uentry_whereDefined (ue)))
09306 {
09307 ;
09308 }
09309 else
09310 {
09311 int scope;
09312
09313 if (uentry_isExpandedMacro (ue))
09314 {
09315 scope = globScope;
09316 }
09317 else
09318 {
09319 if (uentry_isExpandedMacro (ue))
09320 {
09321 scope = fileScope;
09322 }
09323 else if (uentry_isVariable (ue))
09324 {
09325 sRef sr = uentry_getSref (ue);
09326
09327 if (sRef_isValid (sr))
09328 {
09329 scope = sRef_getScope (sr);
09330 }
09331 else
09332 {
09333 scope = fileScope;
09334 }
09335 }
09336 else if (uentry_isFunction (ue)
09337 || uentry_isIter (ue)
09338 || uentry_isEndIter (ue)
09339 || uentry_isConstant (ue))
09340 {
09341 scope = uentry_isStatic (ue) ? fileScope : globScope;
09342 }
09343 else
09344 {
09345 scope = globScope;
09346 }
09347
09348 usymtab_checkDistinctName (ue, scope);
09349 }
09350
09351 if (context_getFlag (FLG_CPPNAMES))
09352 {
09353 if (checkCppName (uentry_rawName (ue), uentry_whereLast (ue)))
09354 {
09355 uentry_setHasNameError (ue);
09356 }
09357 }
09358
09359 if (scope == globScope)
09360 {
09361 checkGlobalName (ue);
09362
09363 if (context_getFlag (FLG_ANSIRESERVED))
09364 {
09365 if (uentry_hasName (ue)
09366 && !uentry_isAnyTag (ue))
09367 {
09368 if (checkAnsiName (uentry_rawName (ue),
09369 uentry_whereLast (ue)))
09370 {
09371 uentry_setHasNameError (ue);
09372 }
09373 }
09374 }
09375 }
09376 else
09377 {
09378 checkLocalName (ue);
09379
09380 if (context_getFlag (FLG_ANSIRESERVEDLOCAL))
09381 {
09382 if (uentry_hasName (ue)
09383 && !uentry_isAnyTag (ue))
09384 {
09385 if (checkAnsiName (uentry_rawName (ue),
09386 uentry_whereLast (ue)))
09387 {
09388 uentry_setHasNameError (ue);
09389 }
09390 }
09391 }
09392 }
09393
09394 DPRINTF (("Check prefix: %s", uentry_unparse (ue)));
09395 checkPrefix (ue);
09396 }
09397 }
09398 }
09399
09400 uentry uentry_makeUnrecognized (cstring c, fileloc loc)
09401 {
09402 uentry ue;
09403 fileloc tloc;
09404
09405
09406
09407 if (!context_inMacro ())
09408 {
09409 sRef_setGlobalScopeSafe ();
09410 }
09411
09412 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
09413 uentry_setUsed (ue, loc);
09414
09415 tloc = fileloc_createExternal ();
09416 uentry_setDefined (ue, tloc);
09417 fileloc_free (tloc);
09418 uentry_setHasNameError (ue);
09419
09420 if (context_getFlag (FLG_REPEATUNRECOG))
09421 {
09422 uentry_markOwned (ue);
09423 }
09424 else
09425 {
09426 ue = usymtab_supReturnFileEntry (ue);
09427 }
09428
09429 if (!context_inMacro ())
09430 {
09431 sRef_clearGlobalScopeSafe ();
09432 }
09433
09434 return ue;
09435 }
09436
09437
09438
09439