00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 # include "lclintMacros.nf"
00032 # include "llbasic.h"
00033 # include "cgrammar.h"
00034
00035 # ifndef NOLCL
00036 # include "usymtab_interface.h"
00037 # endif
00038
00039 # include "structNames.h"
00040 # include "nameChecks.h"
00041
00042 # ifdef SANITIZER
00043 # include "sgrammar_tokens.h"
00044 # else
00045 # include "cgrammar_tokens.h"
00046 # endif
00047
00048
00049
00050
00051
00052
00053
00054 static sRefSet fcnModifies = sRefSet_undefined;
00055 static specialClauses specClauses = specialClauses_undefined;
00056 static bool fcnNoGlobals = FALSE;
00057 static bool ProcessingVars = FALSE;
00058 static bool ProcessingParams = FALSE;
00059 static bool ProcessingGlobals = FALSE;
00060 static bool ProcessingTypedef = FALSE;
00061 static bool ProcessingIterVars = FALSE;
00062 static qtype processingType = qtype_undefined;
00063 static uentry currentIter = uentry_undefined;
00064 static globSet currentGlobals = globSet_undefined;
00065 static uentryList saveParamList;
00066 static uentry saveFunction = uentry_undefined;
00067 static int saveIterParamNo;
00068 static idDecl fixStructDecl ( idDecl p_d);
00069 static void checkTypeDecl (uentry p_e, ctype p_rep);
00070 static fileloc saveStoreLoc = fileloc_undefined;
00071 static storageClassCode storageClass = SCNONE;
00072 static void declareEnumList ( enumNameList p_el, ctype p_c, fileloc p_loc);
00073 static void resetGlobals (void);
00074 static qual specialFunctionCode = QU_UNKNOWN;
00075 static bool argsUsed = FALSE;
00076
00077 static bool hasSpecialCode (void)
00078 {
00079 return (specialFunctionCode != QU_UNKNOWN);
00080 }
00081
00082 extern void setArgsUsed (void)
00083 {
00084 if (argsUsed)
00085 {
00086 voptgenerror
00087 (FLG_SYNTAX,
00088 cstring_makeLiteral ("Multiple ARGSUSED comments for one function"),
00089 g_currentloc);
00090 }
00091
00092 argsUsed = TRUE;
00093 }
00094
00095 static void reflectArgsUsed (uentry ue)
00096 {
00097 if (argsUsed)
00098 {
00099 if (uentry_isFunction (ue))
00100 {
00101 uentryList params = uentry_getParams (ue);
00102
00103 uentryList_elements (params, el)
00104 {
00105 uentry_setUsed (el, fileloc_undefined);
00106 } end_uentryList_elements ;
00107 }
00108
00109 argsUsed = FALSE;
00110 }
00111 }
00112
00113 extern void setSpecialFunction (qual qu)
00114 {
00115 if (specialFunctionCode != QU_UNKNOWN)
00116 {
00117 voptgenerror (FLG_SYNTAX,
00118 message ("Multiple special function codes: %s, %s "
00119 "(first code is ignored)",
00120 qual_unparse (specialFunctionCode),
00121 qual_unparse (qu)),
00122 g_currentloc);
00123 }
00124
00125 specialFunctionCode = qu;
00126 }
00127
00128 static void reflectSpecialCode (uentry ue)
00129 {
00130 switch (specialFunctionCode)
00131 {
00132 case QU_UNKNOWN: break;
00133 case QU_PRINTFLIKE:
00134 uentry_setPrintfLike (ue);
00135 break;
00136 case QU_SCANFLIKE:
00137 uentry_setScanfLike (ue);
00138 break;
00139 case QU_MESSAGELIKE:
00140 uentry_setMessageLike (ue);
00141 break;
00142 BADDEFAULT;
00143 }
00144
00145 specialFunctionCode = QU_UNKNOWN;
00146 }
00147
00148 static void resetStorageClass (void)
00149 {
00150 qtype_free (processingType);
00151 processingType = qtype_undefined;
00152 storageClass = SCNONE;
00153 }
00154
00155 static void reflectModGlobs (uentry ue)
00156 {
00157 if (fcnNoGlobals)
00158 {
00159 llassert (globSet_isUndefined (currentGlobals));
00160
00161 uentry_setGlobals (ue, globSet_undefined);
00162 fcnNoGlobals = FALSE;
00163 }
00164 else if (globSet_isDefined (currentGlobals))
00165 {
00166 uentry_setGlobals (ue, currentGlobals);
00167 currentGlobals = globSet_undefined;
00168 }
00169 else
00170 {
00171 ;
00172 }
00173
00174 if (sRefSet_isDefined (fcnModifies))
00175 {
00176 uentry_setModifies (ue, fcnModifies);
00177 fcnModifies = sRefSet_undefined;
00178 }
00179
00180 if (uentry_isFunction (ue))
00181 {
00182 uentry_setSpecialClauses (ue, specClauses);
00183 specClauses = NULL;
00184 DPRINTF (("Done with spec clauses"));
00185 }
00186 }
00187
00188 static void reflectStorageClass (uentry u)
00189 {
00190 if (storageClass == SCSTATIC)
00191 {
00192 uentry_setStatic (u);
00193 }
00194 else if (storageClass == SCEXTERN)
00195 {
00196 uentry_setExtern (u);
00197 }
00198 else
00199 {
00200 ;
00201 }
00202
00203 }
00204
00205 void storeLoc ()
00206 {
00207 saveStoreLoc = g_currentloc;
00208 }
00209
00210 void setFunctionNoGlobals (void)
00211 {
00212 llassert (globSet_isUndefined (currentGlobals));
00213 fcnNoGlobals = TRUE;
00214 }
00215
00216 void
00217 setFunctionStateSpecialClause (lltok stok, specialClauseKind kind,
00218 sRefSet s,
00219 lltok etok)
00220 {
00221 int tok = lltok_getTok (stok);
00222
00223 switch (tok)
00224 {
00225 case QPRECLAUSE:
00226 specClauses = specialClauses_add (specClauses,
00227 specialClause_create (TK_BEFORE, kind, s));
00228 break;
00229 case QPOSTCLAUSE:
00230 specClauses = specialClauses_add (specClauses,
00231 specialClause_create (TK_AFTER, kind, s));
00232 break;
00233 default:
00234 sRefSet_free (s);
00235 BADBRANCH;
00236 }
00237
00238 DPRINTF (("Added to specclauses: %s", specialClauses_unparse (specClauses)));
00239 }
00240
00241 void setFunctionSpecialClause (lltok stok, sRefSet s,
00242 lltok etok)
00243 {
00244 int tok = lltok_getTok (stok);
00245
00246 switch (tok)
00247 {
00248 case QUSES:
00249 specClauses = specialClauses_add (specClauses, specialClause_createUses (s));
00250 break;
00251 case QDEFINES:
00252 specClauses = specialClauses_add (specClauses, specialClause_createDefines (s));
00253 break;
00254 case QALLOCATES:
00255 specClauses = specialClauses_add (specClauses, specialClause_createAllocates (s));
00256 break;
00257 case QSETS:
00258 specClauses = specialClauses_add (specClauses, specialClause_createSets (s));
00259 break;
00260 case QRELEASES:
00261 specClauses = specialClauses_add (specClauses, specialClause_createReleases (s));
00262 break;
00263 default:
00264 sRefSet_free (s);
00265 BADBRANCH;
00266 }
00267
00268 DPRINTF (("Added to specclauses: %s", specialClauses_unparse (specClauses)));
00269 }
00270
00271 void setFunctionModifies (sRefSet s)
00272 {
00273 sRefSet_free (fcnModifies);
00274 fcnModifies = s;
00275 }
00276
00277 static void reflectGlobalQualifiers (sRef sr, qualList quals)
00278 {
00279 qualList_elements (quals, qel)
00280 {
00281 if (qual_isGlobalQual (qel))
00282 {
00283 sstate oldstate = sRef_getDefState (sr);
00284 sstate defstate = sstate_fromQual (qel);
00285
00286 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
00287 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
00288 {
00289 defstate = SS_UNDEFKILLED;
00290 }
00291 else
00292 {
00293 ;
00294 }
00295
00296 sRef_setDefState (sr, defstate, fileloc_undefined);
00297 }
00298 else if (qual_isAllocQual (qel))
00299 {
00300 ctype realType = sRef_getType (sr);
00301 sstate defstate = sstate_fromQual (qel);
00302
00303 if (qual_isRelDef (qel))
00304 {
00305 ;
00306 }
00307 else
00308 {
00309 if (!ctype_isAP (realType)
00310 && !ctype_isSU (realType)
00311 && !ctype_isUnknown (realType)
00312 && !ctype_isAbstract (sRef_getType (sr)))
00313 {
00314 llerror
00315 (FLG_SYNTAX,
00316 message ("Qualifier %s used on non-pointer or struct: %q",
00317 qual_unparse (qel), sRef_unparse (sr)));
00318
00319 }
00320 }
00321
00322 sRef_setDefState (sr, defstate, fileloc_undefined);
00323 }
00324 else if (qual_isNull (qel))
00325 {
00326 sRef_setNullState (sr, NS_POSNULL, fileloc_undefined);
00327 }
00328 else if (qual_isRelNull (qel))
00329 {
00330 sRef_setNullState (sr, NS_RELNULL, fileloc_undefined);
00331 }
00332 else if (qual_isNotNull (qel))
00333 {
00334 sRef_setNullState (sr, NS_MNOTNULL, fileloc_undefined);
00335 }
00336 else
00337 {
00338 if (qual_isCQual (qel))
00339 {
00340 ;
00341 }
00342 else
00343 {
00344 llerror (FLG_SYNTAX,
00345 message ("Qualifier %s cannot be used in a globals list",
00346 qual_unparse (qel)));
00347 }
00348 }
00349 } end_qualList_elements;
00350 }
00351
00352 void globListAdd (sRef sr, qualList quals)
00353 {
00354 if (sRef_isValid (sr))
00355 {
00356 sRef sc = sRef_copy (sr);
00357
00358 reflectGlobalQualifiers (sc, quals);
00359 currentGlobals = globSet_insert (currentGlobals, sc);
00360 }
00361 }
00362
00363 extern void declareCIter (cstring name, uentryList params)
00364 {
00365 uentry ue;
00366
00367 ue = uentry_makeIter (name,
00368 ctype_makeFunction (ctype_void, params),
00369 fileloc_copy (g_currentloc));
00370
00371 usymtab_supEntry (uentry_makeEndIter (name, fileloc_copy (g_currentloc)));
00372
00373 reflectModGlobs (ue);
00374
00375 ue = usymtab_supGlobalEntryReturn (ue);
00376 }
00377
00378 extern void nextIterParam (void)
00379 {
00380 llassert (ProcessingIterVars);
00381 saveIterParamNo++;
00382 }
00383
00384 extern int iterParamNo (void)
00385 {
00386 llassert (ProcessingIterVars);
00387 return saveIterParamNo;
00388 }
00389
00390
00391
00392
00393
00394 uentry
00395 makeCurrentParam (idDecl t)
00396 {
00397 uentry ue;
00398
00399 saveStoreLoc = fileloc_undefined;
00400
00401
00402
00403 ue = uentry_makeParam (t, 0);
00404 return ue;
00405 }
00406
00407 ctype
00408 declareUnnamedEnum (enumNameList el)
00409 {
00410 ctype ret = usymtab_enumEnumNameListType (el);
00411 ctype rt;
00412 uentry e;
00413
00414 if (ctype_isDefined (ret))
00415 {
00416 rt = ret;
00417 e = uentry_makeEnumTagLoc (ctype_enumTag (rt), ret);
00418
00419 reflectStorageClass (e);
00420 usymtab_supGlobalEntry (e);
00421
00422 declareEnumList (el, ret, g_currentloc);
00423 enumNameList_free (el);
00424 }
00425 else
00426 {
00427 ctype ct = ctype_createEnum (fakeTag (), el);
00428
00429 e = uentry_makeEnumTagLoc (ctype_enumTag (ctype_realType (ct)), ct);
00430 reflectStorageClass (e);
00431
00432 e = usymtab_supGlobalEntryReturn (e);
00433 rt = uentry_getAbstractType (e);
00434 declareEnumList (el, ct, g_currentloc);
00435 }
00436
00437 return (rt);
00438 }
00439
00440 ctype
00441 declareEnum (cstring ename, enumNameList el)
00442 {
00443 ctype cet;
00444 uentry e;
00445
00446 llassert (cstring_isDefined (ename));
00447
00448 cet = ctype_createEnum (ename, el);
00449 e = uentry_makeEnumTagLoc (ename, cet);
00450 reflectStorageClass (e);
00451 e = usymtab_supGlobalEntryReturn (e);
00452 cet = uentry_getType (e);
00453 declareEnumList (el, cet, uentry_whereLast (e));
00454 return (uentry_getAbstractType (e));
00455 }
00456
00457 static void
00458 declareEnumList (enumNameList el, ctype c, fileloc loc)
00459 {
00460 bool boolnames = FALSE;
00461 bool othernames = FALSE;
00462
00463 (void) context_getSaveLocation ();
00464
00465 if (context_maybeSet (FLG_NUMENUMMEMBERS))
00466 {
00467 int maxnum = context_getValue (FLG_NUMENUMMEMBERS);
00468 int num = enumNameList_size (el);
00469
00470 if (num > maxnum)
00471 {
00472 voptgenerror
00473 (FLG_NUMENUMMEMBERS,
00474 message ("Enumerator %s declared with %d members (limit is set to %d)",
00475 ctype_unparse (c), num, maxnum),
00476 loc);
00477 }
00478 }
00479
00480 enumNameList_elements (el, e)
00481 {
00482 uentry ue = usymtab_lookupExposeGlob (e);
00483 ctype ct = uentry_getType (ue);
00484
00485 llassert (uentry_isEnumConstant (ue));
00486
00487 if (ctype_isUnknown (ct))
00488 {
00489 uentry_setType (ue, c);
00490 }
00491 else
00492 {
00493 if (cstring_equal (e, context_getFalseName ())
00494 || cstring_equal (e, context_getTrueName ()))
00495 {
00496 if (othernames)
00497 {
00498 if (optgenerror
00499 (FLG_INCONDEFS,
00500 message ("Enumerator mixes boolean name (%s) with "
00501 "non-boolean names",
00502 e),
00503 uentry_whereLast (ue)))
00504 {
00505 ;
00506 }
00507 }
00508
00509 boolnames = TRUE;
00510 uentry_setType (ue, ctype_bool);
00511 DPRINTF (("Set type: %s / %s",
00512 uentry_unparse (ue), ctype_unparse (ctype_bool)));
00513 }
00514 else
00515 {
00516 if (boolnames)
00517 {
00518 if (optgenerror
00519 (FLG_INCONDEFS,
00520 message ("Enumerator mixes boolean names (%s, %s) with "
00521 "non-boolean name: %s",
00522 context_getTrueName (),
00523 context_getFalseName (),
00524 e),
00525 uentry_whereLast (ue)))
00526 {
00527 ;
00528 }
00529 }
00530
00531 othernames = TRUE;
00532 }
00533
00534 if (!ctype_match (c, ct))
00535 {
00536 if (ctype_isDirectBool (ct))
00537 {
00538 if (cstring_equal (e, context_getFalseName ())
00539 || cstring_equal (e, context_getTrueName ()))
00540 {
00541 DPRINTF (("Here we are!"));
00542 }
00543 else
00544 {
00545 if (optgenerror
00546 (FLG_INCONDEFS,
00547 message ("Enumerator member %s declared with "
00548 "inconsistent type: %s",
00549 e, ctype_unparse (c)),
00550 uentry_whereLast (ue)))
00551 {
00552 uentry_showWhereSpecifiedExtra
00553 (ue, cstring_copy (ctype_unparse (ct)));
00554 }
00555 }
00556 }
00557 else
00558 {
00559 if (optgenerror
00560 (FLG_INCONDEFS,
00561 message ("Enumerator member %s declared with "
00562 "inconsistent type: %s",
00563 e, ctype_unparse (c)),
00564 uentry_whereLast (ue)))
00565 {
00566 uentry_showWhereSpecifiedExtra
00567 (ue, cstring_copy (ctype_unparse (ct)));
00568 }
00569 }
00570 }
00571 }
00572 } end_enumNameList_elements;
00573 }
00574
00575 static uentryList currentParamList;
00576
00577 void setCurrentParams ( uentryList ue)
00578 {
00579 currentParamList = ue;
00580 }
00581
00582 void clearCurrentParams (void)
00583 {
00584 currentParamList = uentryList_undefined;
00585 }
00586
00587
00588
00589
00590
00591
00592 static void enterFunctionParams (uentryList params)
00593 {
00594 int paramno = 0;
00595
00596 uentryList_elements (params, current)
00597 {
00598 if (uentry_hasName (current))
00599 {
00600 uentry_setParamNo (current, paramno);
00601 usymtab_supEntry (uentry_copy (current));
00602 }
00603
00604 paramno++;
00605 } end_uentryList_elements;
00606 }
00607
00608
00609 extern void enterParamsTemp (void)
00610 {
00611 usymtab_enterScope ();
00612 enterFunctionParams (currentParamList);
00613 }
00614
00615 extern void exitParamsTemp (void)
00616 {
00617 usymtab_quietPlainExitScope ();
00618 }
00619
00620 static uentry globalDeclareFunction (idDecl tid)
00621 {
00622 ctype deftype = idDecl_getCtype (tid);
00623 ctype rettype;
00624 uentry ue;
00625
00626 DPRINTF (("Global function: %s", idDecl_unparse (tid)));
00627
00628 if (ctype_isFunction (deftype))
00629 {
00630 rettype = ctype_returnValue (deftype);
00631 }
00632 else
00633 {
00634 rettype = ctype_unknown;
00635 }
00636
00637
00638
00639
00640
00641 if (ctype_isFunction (idDecl_getCtype (tid)))
00642 {
00643 ue = uentry_makeIdFunction (tid);
00644 reflectSpecialCode (ue);
00645 reflectArgsUsed (ue);
00646 }
00647 else
00648 {
00649 llparseerror (message ("Inconsistent function declaration: %q",
00650 idDecl_unparse (tid)));
00651
00652 tid = idDecl_replaceCtype
00653 (tid, ctype_makeFunction (ctype_unknown, uentryList_undefined));
00654 ue = uentry_makeIdFunction (tid);
00655 }
00656
00657 reflectStorageClass (ue);
00658
00659 uentry_checkParams (ue);
00660 reflectModGlobs (ue);
00661
00662 ue = usymtab_supGlobalEntryReturn (ue);
00663 context_enterFunction (ue);
00664 enterFunctionParams (uentry_getParams (ue));
00665
00666 resetStorageClass ();
00667 return (ue);
00668 }
00669
00670
00671
00672
00673
00674
00675 static uentry globalDeclareOldStyleFunction (idDecl tid)
00676 {
00677 uentry ue;
00678
00679
00680
00681
00682
00683 if (cstring_equalLit (idDecl_observeId (tid), "main"))
00684 {
00685 context_setFlagTemp (FLG_MAINTYPE, FALSE);
00686 }
00687
00688 ue = uentry_makeIdFunction (tid);
00689 reflectStorageClass (ue);
00690 reflectSpecialCode (ue);
00691 reflectArgsUsed (ue);
00692 uentry_setDefined (ue, g_currentloc);
00693
00694 uentry_checkParams (ue);
00695
00696 if (ProcessingGlobals)
00697 {
00698 uentry_setGlobals (ue, currentGlobals);
00699 }
00700
00701 resetStorageClass ();
00702 return (ue);
00703 }
00704
00705 static void oldStyleDeclareFunction ( uentry e)
00706 {
00707 uentryList params = saveParamList;
00708 ctype rt = uentry_getType (e);
00709
00710 llassert (ctype_isFunction (rt));
00711
00712 e = usymtab_supGlobalEntryReturn (e);
00713
00714 context_enterFunction (e);
00715 enterFunctionParams (params);
00716 saveParamList = uentryList_undefined;
00717 resetStorageClass ();
00718 }
00719
00720 void declareFunction (idDecl tid)
00721 {
00722 uentry ue;
00723
00724 DPRINTF (("Declare function: %s", idDecl_unparse (tid)));
00725
00726 if (ProcessingParams)
00727 {
00728 ue = globalDeclareOldStyleFunction (tid);
00729 saveFunction = ue;
00730 }
00731 else
00732 {
00733 saveFunction = uentry_undefined;
00734
00735 if (context_inRealFunction ())
00736 {
00737 ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
00738
00739 llparseerror (message ("Function declared inside function: %q",
00740 idDecl_unparse (tid)));
00741
00742 context_quietExitFunction ();
00743 ue = usymtab_supEntryReturn (ue);
00744 }
00745 else
00746 {
00747 if (context_inInnerScope ())
00748 {
00749 llparseerror (message ("Declaration in inner context: %q",
00750 idDecl_unparse (tid)));
00751
00752 sRef_setGlobalScope ();
00753 ue = uentry_makeVariableLoc (idDecl_observeId (tid),
00754 ctype_unknown);
00755 ue = usymtab_supGlobalEntryReturn (ue);
00756 sRef_clearGlobalScope ();
00757 }
00758 else
00759 {
00760 ue = globalDeclareFunction (tid);
00761 }
00762 }
00763
00764 resetGlobals ();
00765 }
00766
00767 resetStorageClass ();
00768 idDecl_free (tid);
00769 }
00770
00771 void declareStaticFunction (idDecl tid)
00772 {
00773 uentry ue;
00774
00775 DPRINTF (("Declare static funciton: %s", idDecl_unparse (tid)));
00776
00777 if (ProcessingParams)
00778 {
00779 ue = globalDeclareOldStyleFunction (tid);
00780 saveFunction = ue;
00781 }
00782 else
00783 {
00784 saveFunction = uentry_undefined;
00785
00786 if (context_inRealFunction ())
00787 {
00788 ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
00789
00790 llparseerror (message ("Function declared inside function: %q",
00791 idDecl_unparse (tid)));
00792
00793 context_quietExitFunction ();
00794 ue = usymtab_supEntryReturn (ue);
00795 }
00796 else
00797 {
00798 if (context_inInnerScope ())
00799 {
00800 llparseerror (message ("Declaration in inner context: %q",
00801 idDecl_unparse (tid)));
00802
00803 sRef_setGlobalScope ();
00804 ue = uentry_makeVariableLoc (idDecl_observeId (tid),
00805 ctype_unknown);
00806 ue = usymtab_supGlobalEntryReturn (ue);
00807 sRef_clearGlobalScope ();
00808 }
00809 else
00810 {
00811 ctype deftype = idDecl_getCtype (tid);
00812 ctype rettype;
00813
00814 if (ctype_isFunction (deftype))
00815 {
00816 rettype = ctype_returnValue (deftype);
00817 }
00818 else
00819 {
00820 rettype = ctype_unknown;
00821 }
00822
00823
00824
00825
00826
00827 if (ctype_isFunction (idDecl_getCtype (tid)))
00828 {
00829 ue = uentry_makeIdFunction (tid);
00830 reflectSpecialCode (ue);
00831 reflectArgsUsed (ue);
00832 }
00833 else
00834 {
00835 llparseerror (message ("Inconsistent function declaration: %q",
00836 idDecl_unparse (tid)));
00837
00838 tid = idDecl_replaceCtype
00839 (tid, ctype_makeFunction (ctype_unknown, uentryList_undefined));
00840 ue = uentry_makeIdFunction (tid);
00841 }
00842
00843 reflectStorageClass (ue);
00844 uentry_setStatic (ue);
00845
00846 uentry_checkParams (ue);
00847 reflectModGlobs (ue);
00848
00849 DPRINTF (("Sub global entry: %s", uentry_unparse (ue)));
00850 ue = usymtab_supGlobalEntryReturn (ue);
00851
00852 context_enterFunction (ue);
00853 enterFunctionParams (uentry_getParams (ue));
00854 resetStorageClass ();
00855 }
00856 }
00857
00858 resetGlobals ();
00859 }
00860
00861 resetStorageClass ();
00862 idDecl_free (tid);
00863 }
00864
00865 void
00866 checkTypeDecl (uentry e, ctype rep)
00867 {
00868 cstring n = uentry_getName (e);
00869
00870 DPRINTF (("Check type decl: %s", n));
00871
00872 if (cstring_equal (context_getBoolName (), n))
00873 {
00874 ctype rrep = ctype_realType (rep);
00875
00876
00877
00878
00879
00880
00881 if (ctype_isEnum (ctype_realType (rrep)))
00882 {
00883 enumNameList el = ctype_elist (rrep);
00884
00885 enumNameList_elements (el, ye)
00886 {
00887 if (usymtab_existsGlob (ye))
00888 {
00889 uentry ue = usymtab_lookupSafe (ye);
00890 uentry_setType (ue, ctype_bool);
00891 }
00892
00893 if (cstring_equal (context_getTrueName (), ye)
00894 || cstring_equal (context_getFalseName (), ye))
00895 {
00896 ;
00897 }
00898 else
00899 {
00900 vgenhinterror
00901 (FLG_SYNTAX,
00902 message ("Member of boolean enumerated type definition "
00903 "does not match name set to represent TRUE "
00904 "or FALSE: %s",
00905 ye),
00906 message ("Use -boolfalse and -booltrue to set the "
00907 "name of false and true boolean values."),
00908 uentry_whereDefined (e));
00909 }
00910 } end_enumNameList_elements;
00911 }
00912 }
00913
00914 if (usymtab_exists (n))
00915 {
00916 usymId llm = usymtab_getId (n);
00917 uentry le = usymtab_getTypeEntry (llm);
00918
00919 uentry_setDeclared (e, g_currentloc);
00920 uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le)));
00921
00922 DPRINTF (("Here we are: %s / %s",
00923 n, context_getBoolName ()));
00924
00925 if (uentry_isAbstractDatatype (le))
00926 {
00927 ctype rrep = ctype_realType (rep);
00928
00929
00930
00931
00932
00933
00934 if (ctype_isEnum (ctype_realType (rrep)))
00935 {
00936 ctype at = uentry_getAbstractType (le);
00937 enumNameList el = ctype_elist (rrep);
00938
00939 enumNameList_elements (el, ye)
00940 {
00941 if (usymtab_existsGlob (ye))
00942 {
00943 uentry ue = usymtab_lookupSafe (ye);
00944
00945 llassert (uentry_isEitherConstant (ue));
00946 llassertprint (ctype_match (uentry_getType (ue), rrep),
00947 ("Bad enum: %s / %s",
00948 uentry_unparse (ue),
00949 ctype_unparse (rrep)));
00950
00951 uentry_setType (ue, at);
00952 }
00953 } end_enumNameList_elements;
00954 }
00955
00956 if (uentry_isMutableDatatype (le))
00957 {
00958
00959
00960 if (!ctype_isRealPointer (rep) && !ctype_isRealAbstract (rep))
00961 {
00962 voptgenerror
00963 (FLG_MUTREP,
00964 message ("Mutable abstract type %s declared without pointer "
00965 "indirection: %s (violates assignment semantics)",
00966 n, ctype_unparse (rep)),
00967 uentry_whereDefined (e));
00968
00969 uentry_setMutable (e);
00970 }
00971 }
00972 }
00973 }
00974 else
00975 {
00976 fileloc fl = uentry_whereDeclared (e);
00977
00978 if (context_getFlag (FLG_LIKELYBOOL)
00979 && !context_getFlag (FLG_BOOLINT))
00980 {
00981 if ((cstring_equalLit (n, "BOOL")
00982 || cstring_equalLit (n, "Bool")
00983 || cstring_equalLit (n, "bool")
00984 || cstring_equalLit (n, "boolean")
00985 || cstring_equalLit (n, "Boolean")
00986 || cstring_equalLit (n, "BOOLEAN"))
00987 && !(cstring_equal (n, context_getBoolName ())))
00988 {
00989 if (context_setBoolName ()) {
00990 voptgenerror
00991 (FLG_LIKELYBOOL,
00992 message ("Type %s is probably meant as a boolean type, but does "
00993 "not match the boolean type name \"%s\".",
00994 n,
00995 context_getBoolName ()),
00996 fl);
00997 } else
00998 voptgenerror
00999 (FLG_LIKELYBOOL,
01000 message ("Type %s is probably meant as a boolean type, "
01001 "but the boolean type name is not set. "
01002 "Use -booltype %s to set it.",
01003 n,
01004 n),
01005 fl);
01006 }
01007 }
01008
01009 if (!uentry_isStatic (e)
01010 && !ctype_isFunction (uentry_getType (e))
01011 && !fileloc_isLib (fl)
01012 && !fileloc_isImport (fl)
01013 && fileloc_isHeader (fl))
01014 {
01015 voptgenerror (FLG_EXPORTTYPE,
01016 message ("Type exported, but not specified: %s\n", n),
01017 fl);
01018 }
01019 }
01020
01021 cstring_free (n);
01022 }
01023
01024 uentryList
01025 fixUentryList (idDeclList tl, qtype q)
01026 {
01027 uentryList f = uentryList_new ();
01028
01029 idDeclList_elements (tl, i)
01030 {
01031 if (idDecl_isDefined (i))
01032 {
01033 uentry ue;
01034 uentry old;
01035 ctype rt;
01036
01037 (void) idDecl_fixBase (i, q);
01038
01039
01040
01041
01042
01043 (void) fixStructDecl (i);
01044
01045 ue = uentry_makeIdVariable (i);
01046 rt = ctype_realType (uentry_getType (ue));
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 if (uentry_isValid (old = uentryList_lookupField (f, uentry_rawName (ue))))
01060 {
01061 if (optgenerror (FLG_SYNTAX,
01062 message ("Field name reused: %s", uentry_rawName (ue)),
01063 uentry_whereDefined (ue)))
01064 {
01065 llgenmsg (message ("Previous use of %s", uentry_rawName (ue)),
01066 uentry_whereDefined (old));
01067 }
01068 }
01069
01070 f = uentryList_add (f, ue);
01071 }
01072 } end_idDeclList_elements;
01073
01074 idDeclList_free (tl);
01075 return (f);
01076 }
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 uentryList
01088 fixUnnamedDecl (qtype q)
01089 {
01090 ctype ct = ctype_realType (qtype_getType (q));
01091
01092 if (ctype_isStruct (ct) || ctype_isUnion (ct))
01093 {
01094 uentryList res = ctype_getFields (ct);
01095
01096 return (uentryList_copy (res));
01097 }
01098 else
01099 {
01100 BADBRANCHCONT;
01101 }
01102
01103 return uentryList_undefined;
01104 }
01105
01106 void setStorageClass (storageClassCode sc)
01107 {
01108 storageClass = sc;
01109 }
01110
01111 void
01112 setProcessingIterVars (uentry iter)
01113 {
01114 ProcessingIterVars = TRUE;
01115 currentIter = iter;
01116 saveIterParamNo = 0;
01117 }
01118
01119 void
01120 setProcessingGlobalsList ()
01121 {
01122 ProcessingGlobals = TRUE;
01123
01124 llassert (globSet_isUndefined (currentGlobals));
01125 currentGlobals = globSet_undefined;
01126
01127 llassert (sRefSet_isUndefined (fcnModifies));
01128 fcnModifies = sRefSet_undefined;
01129
01130
01131
01132
01133
01134
01135
01136 fcnNoGlobals = FALSE;
01137 }
01138
01139 static bool ProcessingGlobMods = FALSE;
01140
01141 void
01142 setProcessingGlobMods ()
01143 {
01144 ProcessingGlobMods = TRUE;
01145 }
01146
01147 void
01148 clearProcessingGlobMods ()
01149 {
01150 ProcessingGlobMods = FALSE;
01151 }
01152
01153 bool
01154 isProcessingGlobMods ()
01155 {
01156 return (ProcessingGlobMods);
01157 }
01158
01159 static void resetGlobals (void)
01160 {
01161 ProcessingGlobals = FALSE;
01162 currentGlobals = globSet_undefined;
01163 llassert (sRefSet_isUndefined (fcnModifies));
01164 fcnModifies = sRefSet_undefined;
01165 fcnNoGlobals = FALSE;
01166 }
01167
01168 void
01169 unsetProcessingGlobals ()
01170 {
01171 ProcessingGlobals = FALSE;
01172 }
01173
01174 void
01175 setProcessingVars ( qtype q)
01176 {
01177 ProcessingVars = TRUE;
01178 qtype_free (processingType);
01179 processingType = q;
01180 }
01181
01182 static void
01183 setGenericParamList ( uentryList pm)
01184 {
01185 ProcessingParams = TRUE;
01186 saveParamList = pm;
01187 }
01188
01189 void
01190 setProcessingTypedef ( qtype q)
01191 {
01192 ProcessingTypedef = TRUE;
01193
01194 qtype_free (processingType);
01195 processingType = q;
01196 }
01197
01198 void
01199 unsetProcessingVars ()
01200 {
01201 resetStorageClass ();
01202 ProcessingVars = FALSE;
01203 }
01204
01205 void
01206 doneParams ()
01207 {
01208 if (ProcessingParams)
01209 {
01210 if (uentry_isInvalid (saveFunction))
01211 {
01212 llbuglit ("unsetProcessingVars: no saved function\n");
01213
01214 if (sRefSet_isDefined (fcnModifies)) {
01215 sRefSet_free (fcnModifies);
01216 fcnModifies = sRefSet_undefined;
01217 }
01218 }
01219 else
01220 {
01221 ctype ct = ctype_returnValue (uentry_getType (saveFunction));
01222 uentryList params = uentryList_copy (saveParamList);
01223 ctype ct2 = ctype_makeFunction (ct, params);
01224
01225 uentry_setType (saveFunction, ct2);
01226 ProcessingParams = FALSE;
01227
01228 reflectModGlobs (saveFunction);
01229 oldStyleDeclareFunction (saveFunction);
01230 saveFunction = uentry_undefined;
01231 resetGlobals ();
01232 }
01233 }
01234 else
01235 {
01236
01237
01238
01239
01240 llfatalerror (message ("%q: Old-style function parameter list uses a "
01241 "type name.", fileloc_unparse (g_currentloc)));
01242 }
01243 }
01244
01245 void
01246 checkDoneParams ()
01247 {
01248 if (uentry_isValid (saveFunction))
01249 {
01250
01251
01252
01253
01254 ctype ct = ctype_returnValue (uentry_getType (saveFunction));
01255 ctype ct2;
01256
01257 uentryList_elements (saveParamList, current)
01258 {
01259 uentry_setType (current, ctype_int);
01260 } end_uentryList_elements;
01261
01262 ct2 = ctype_makeParamsFunction (ct, uentryList_copy (saveParamList));
01263
01264 uentry_setType (saveFunction, ct2);
01265 ProcessingParams = FALSE;
01266
01267 oldStyleDeclareFunction (saveFunction);
01268 saveFunction = uentry_undefined;
01269 }
01270 }
01271
01272 void
01273 unsetProcessingTypedef ()
01274 {
01275 ProcessingTypedef = FALSE;
01276 }
01277
01278 void checkConstant (qtype t, idDecl id)
01279 {
01280 uentry e;
01281
01282 id = idDecl_fixBase (id, t);
01283 e = uentry_makeIdConstant (id);
01284
01285 reflectStorageClass (e);
01286 resetStorageClass ();
01287
01288 usymtab_supGlobalEntry (e);
01289 }
01290
01291 void checkValueConstant (qtype t, idDecl id, exprNode e)
01292 {
01293 uentry ue;
01294
01295 id = idDecl_fixBase (id, t);
01296 ue = uentry_makeIdConstant (id);
01297 reflectStorageClass (ue);
01298 resetStorageClass ();
01299
01300 if (exprNode_isDefined (e))
01301 {
01302 if (!exprNode_matchType (uentry_getType (ue), e))
01303 {
01304 (void) gentypeerror
01305 (exprNode_getType (e), e,
01306 uentry_getType (ue), exprNode_undefined,
01307 message ("Constant %q initialized to type %t, expects %t: %s",
01308 uentry_getName (ue),
01309 exprNode_getType (e),
01310 uentry_getType (ue),
01311 exprNode_unparse (e)),
01312 exprNode_loc (e));
01313 }
01314 else
01315 {
01316 if (exprNode_hasValue (e))
01317 {
01318 uentry_mergeConstantValue (ue, multiVal_copy (exprNode_getValue (e)));
01319 }
01320 }
01321 }
01322
01323 usymtab_supGlobalEntry (ue);
01324 }
01325
01326
01327 void processNamedDecl (idDecl t)
01328 {
01329 if (qtype_isUndefined (processingType))
01330 {
01331 llparseerror (message ("No type before declaration name: %q", idDecl_unparse (t)));
01332
01333 processingType = qtype_create (ctype_unknown);
01334 }
01335
01336 t = idDecl_fixBase (t, processingType);
01337
01338 DPRINTF (("Declare: %s", idDecl_unparse (t)));
01339
01340 if (ProcessingGlobals)
01341 {
01342 cstring id = idDecl_getName (t);
01343 uentry ue = usymtab_lookupSafe (id);
01344
01345 if (!uentry_isValid (ue))
01346 {
01347 llerror (FLG_UNRECOG,
01348 message ("Variable used in globals list is undeclared: %s", id));
01349 }
01350 else
01351 {
01352 if (!ctype_match (uentry_getType (ue), idDecl_getCtype (t)))
01353 {
01354 voptgenerror
01355 (FLG_INCONDEFS,
01356 message ("Variable %s used in globals list declared %s, "
01357 "but listed as %s",
01358 id, ctype_unparse (uentry_getType (ue)),
01359 ctype_unparse (idDecl_getCtype (t))),
01360 g_currentloc);
01361 }
01362 else
01363 {
01364 sRef sr = sRef_copy (uentry_getSref (ue));
01365
01366 reflectGlobalQualifiers (sr, idDecl_getQuals (t));
01367
01368 currentGlobals = globSet_insert (currentGlobals, sr);
01369 }
01370 }
01371 }
01372 else if (ProcessingVars)
01373 {
01374 uentry e;
01375 ctype ct;
01376
01377 ct = ctype_realType (idDecl_getCtype (t));
01378
01379 if (ProcessingParams)
01380 {
01381 cstring id = idDecl_getName (t);
01382 int paramno = uentryList_lookupRealName (saveParamList, id);
01383
01384 if (paramno >= 0)
01385 {
01386 uentry cparam = uentryList_getN (saveParamList, paramno);
01387
01388 uentry_setType (cparam, idDecl_getCtype (t));
01389 uentry_reflectQualifiers (cparam, idDecl_getQuals (t));
01390 uentry_setDeclaredOnly (cparam, context_getSaveLocation ());
01391 }
01392 else
01393 {
01394 llfatalerrorLoc
01395 (message ("Old style declaration uses unlisted parameter: %s",
01396 id));
01397 }
01398 }
01399 else
01400 {
01401 fileloc loc;
01402
01403 if (context_inIterDef ())
01404 {
01405 cstring pname = makeParam (idDecl_observeId (t));
01406 uentry p = usymtab_lookupSafe (pname);
01407
01408 cstring_free (pname);
01409
01410 if (uentry_isYield (p))
01411 {
01412 e = uentry_makeParam (t, sRef_getParam (uentry_getSref (p)));
01413
01414 uentry_checkYieldParam (p, e);
01415
01416 usymtab_supEntrySref (e);
01417 return;
01418 }
01419 }
01420
01421 if ((hasSpecialCode () || argsUsed)
01422 && ctype_isFunction (idDecl_getCtype (t)))
01423 {
01424 e = uentry_makeIdFunction (t);
01425 reflectSpecialCode (e);
01426 reflectArgsUsed (e);
01427 }
01428 else
01429 {
01430 e = uentry_makeIdVariable (t);
01431 }
01432
01433 loc = uentry_whereDeclared (e);
01434
01435
01436
01437
01438
01439
01440
01441
01442 if (ctype_isFunction (uentry_getType (e)))
01443 {
01444 reflectModGlobs (e);
01445 }
01446 else
01447 {
01448 llassert (!globSet_isDefined (currentGlobals)
01449 && !sRefSet_isDefined (fcnModifies));
01450 }
01451
01452 e = usymtab_supEntrySrefReturn (e);
01453
01454 if (uentry_isExtern (e) && !context_inGlobalScope ())
01455 {
01456 voptgenerror
01457 (FLG_NESTEDEXTERN,
01458 message ("Declaration using extern inside function scope: %q",
01459 uentry_unparse (e)),
01460 g_currentloc);
01461
01462 uentry_setDefined (e, fileloc_getExternal ());
01463 sRef_setDefined (uentry_getSref (e), fileloc_getExternal ());
01464 }
01465
01466 if (uentry_isFunction (e))
01467 {
01468 uentry_checkParams (e);
01469 checkParamNames (e);
01470 }
01471
01472 if (uentry_isVar (e)
01473 && uentry_isCheckedUnknown (e))
01474 {
01475 sRef sr = uentry_getSref (e);
01476
01477 if (sRef_isLocalVar (sr))
01478 {
01479 if (context_getFlag (FLG_IMPCHECKMODINTERNALS))
01480 {
01481 uentry_setCheckMod (e);
01482 }
01483 else
01484 {
01485 uentry_setUnchecked (e);
01486 }
01487 }
01488 else if (sRef_isFileStatic (sr))
01489 {
01490 if (context_getFlag (FLG_IMPCHECKEDSTRICTSTATICS))
01491 {
01492 uentry_setCheckedStrict (e);
01493 }
01494 else if (context_getFlag (FLG_IMPCHECKEDSTATICS))
01495 {
01496 uentry_setChecked (e);
01497 }
01498 else if (context_getFlag (FLG_IMPCHECKMODSTATICS))
01499 {
01500 uentry_setCheckMod (e);
01501 }
01502 else
01503 {
01504 ;
01505 }
01506 }
01507 else
01508 {
01509 llassert (sRef_isRealGlobal (sr));
01510
01511 if (context_getFlag (FLG_IMPCHECKEDSTRICTGLOBALS))
01512 {
01513 uentry_setCheckedStrict (e);
01514 }
01515 else if (context_getFlag (FLG_IMPCHECKEDGLOBALS))
01516 {
01517 uentry_setChecked (e);
01518 }
01519 else if (context_getFlag (FLG_IMPCHECKMODGLOBALS))
01520 {
01521 uentry_setCheckMod (e);
01522 }
01523 else
01524 {
01525 ;
01526 }
01527 }
01528 }
01529 }
01530 }
01531 else if (ProcessingTypedef)
01532 {
01533 ctype ct = idDecl_getCtype (t);
01534 uentry e;
01535
01536 DPRINTF (("Processing typedef: %s", ctype_unparse (ct)));
01537
01538 e = uentry_makeIdDatatype (t);
01539
01540 if (cstring_equal (idDecl_getName (t), context_getBoolName ())) {
01541 ctype rt = ctype_realType (ct);
01542
01543 if (ctype_isEnum (rt)) {
01544 ;
01545 } else {
01546 if (!(ctype_isInt (rt)
01547 || ctype_isUnknown (rt)
01548 || ctype_isChar (rt))) {
01549 (void) llgenerror
01550 (FLG_BOOLTYPE,
01551 message ("Boolean type %s defined using non-standard type %s (integral, char or enum type expected)",
01552 context_getBoolName (),
01553 ctype_unparse (ct)),
01554 uentry_whereLast (e));
01555 }
01556
01557 ct = ctype_bool;
01558 uentry_setType (e, ct);
01559 }
01560 }
01561
01562 reflectStorageClass (e);
01563 checkTypeDecl (e, ct);
01564
01565 e = usymtab_supReturnTypeEntry (e);
01566
01567 if (uentry_isMaybeAbstract (e))
01568 {
01569 if (context_getFlag (FLG_IMPABSTRACT))
01570 {
01571 uentry_setAbstract (e);
01572 }
01573 else
01574 {
01575 uentry_setConcrete (e);
01576 }
01577 }
01578 }
01579 else
01580 {
01581 llparseerror (message ("Suspect missing struct or union keyword: %q",
01582 idDecl_unparse (t)));
01583 }
01584
01585 }
01586
01587
01588
01589
01590
01591 static idDecl fixStructDecl ( idDecl d)
01592 {
01593 if (ctype_isVisiblySharable (idDecl_getCtype (d))
01594 && context_getFlag (FLG_STRUCTIMPONLY))
01595 {
01596 if (!qualList_hasAliasQualifier (idDecl_getQuals (d)))
01597 {
01598 if (qualList_hasExposureQualifier (idDecl_getQuals (d)))
01599 {
01600 idDecl_addQual (d, qual_createDependent ());
01601 }
01602 else
01603 {
01604 idDecl_addQual (d, qual_createImpOnly ());
01605 }
01606 }
01607 }
01608
01609 return d;
01610 }
01611
01612 ctype
01613 declareUnnamedStruct ( uentryList f)
01614 {
01615 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
01616 {
01617 int num = uentryList_size (f);
01618 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
01619
01620 if (num > max)
01621 {
01622 voptgenerror
01623 (FLG_NUMSTRUCTFIELDS,
01624 message ("Structure declared with %d fields "
01625 "(limit is set to %d)",
01626 num, max),
01627 g_currentloc);
01628 }
01629 }
01630
01631 return (ctype_createUnnamedStruct (f));
01632 }
01633
01634 ctype
01635 declareUnnamedUnion ( uentryList f)
01636 {
01637 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
01638 {
01639 int num = uentryList_size (f);
01640 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
01641
01642 if (num > max)
01643 {
01644 voptgenerror
01645 (FLG_NUMSTRUCTFIELDS,
01646 message ("Union declared with %d fields "
01647 "(limit is set to %d)",
01648 num, max),
01649 g_currentloc);
01650 }
01651 }
01652
01653 return (ctype_createUnnamedUnion (f));
01654 }
01655
01656 ctype declareStruct (cstring id, uentryList f)
01657 {
01658 ctype ct;
01659 uentry ue;
01660 int num = uentryList_size (f);
01661
01662 ct = ctype_createStruct (cstring_copy (id), f);
01663 ue = uentry_makeStructTagLoc (id, ct);
01664
01665 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
01666 {
01667 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
01668
01669 if (num > max)
01670 {
01671 voptgenerror
01672 (FLG_NUMSTRUCTFIELDS,
01673 message ("Structure %q declared with %d fields "
01674 "(limit is set to %d)",
01675 uentry_getName (ue), num, max),
01676 uentry_whereLast (ue));
01677 }
01678 }
01679
01680 return (usymtab_supTypeEntry (ue));
01681 }
01682
01683 ctype declareUnion (cstring id, uentryList f)
01684 {
01685 ctype ct;
01686 uentry ue;
01687 int num = uentryList_size (f);
01688
01689 ct = ctype_createUnion (cstring_copy (id), f);
01690 ue = uentry_makeUnionTagLoc (id, ct);
01691
01692 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
01693 {
01694 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
01695
01696 if (num > max)
01697 {
01698 voptgenerror
01699 (FLG_NUMSTRUCTFIELDS,
01700 message ("Union %q declared with %d fields "
01701 "(limit is set to %d)",
01702 uentry_getName (ue), num, max),
01703 uentry_whereLast (ue));
01704 }
01705 }
01706
01707 return (usymtab_supTypeEntry (ue));
01708 }
01709
01710 ctype handleStruct ( cstring id)
01711 {
01712 if (usymtab_existsStructTag (id))
01713 {
01714 ctype ct = uentry_getAbstractType (usymtab_lookupStructTag (id));
01715
01716 cstring_free (id);
01717 return ct;
01718 }
01719 else
01720 {
01721 return (ctype_createForwardStruct (id));
01722 }
01723 }
01724
01725 ctype handleUnion ( cstring id)
01726 {
01727 if (usymtab_existsUnionTag (id))
01728 {
01729 ctype ret = uentry_getAbstractType (usymtab_lookupUnionTag (id));
01730 cstring_free (id);
01731 return (ret);
01732 }
01733 else
01734 {
01735 return (ctype_createForwardUnion (id));
01736 }
01737 }
01738
01739 ctype
01740 handleEnum (cstring id)
01741 {
01742 if (usymtab_existsEnumTag (id))
01743 {
01744 ctype ret = uentry_getAbstractType (usymtab_lookupEnumTag (id));
01745 cstring_free (id);
01746 return ret;
01747 }
01748 else
01749 {
01750 return (declareEnum (id, enumNameList_new ()));
01751 }
01752 }
01753
01754 bool processingIterVars (void)
01755 {
01756 return ProcessingIterVars;
01757 }
01758
01759 uentry getCurrentIter (void)
01760 {
01761 return currentIter;
01762 }
01763
01764 static bool flipOldStyle = FALSE;
01765 static bool flipNewStyle = TRUE;
01766
01767 void setFlipOldStyle () { flipOldStyle = TRUE; }
01768 bool isFlipOldStyle () { return flipOldStyle; }
01769 bool isNewStyle () { return flipNewStyle; }
01770 void setNewStyle () { flipNewStyle = TRUE; }
01771
01772 uentryList handleParamIdList ( uentryList params)
01773 {
01774 int paramno = 0;
01775
01776
01777
01778
01779
01780
01781 voptgenerror (FLG_OLDSTYLE,
01782 cstring_makeLiteral ("Old style function declaration"),
01783 g_currentloc);
01784
01785 uentryList_elements (params, current)
01786 {
01787 uentry_setParam (current);
01788 uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown));
01789 paramno++;
01790 } end_uentryList_elements;
01791
01792 setGenericParamList (params);
01793 g_expectingTypeName = TRUE;
01794
01795 return params;
01796 }
01797
01798 uentryList handleParamTypeList ( uentryList params)
01799 {
01800 if (flipOldStyle)
01801 {
01802 uentryList_fixMissingNames (params);
01803
01804 voptgenerror (FLG_OLDSTYLE,
01805 cstring_makeLiteral ("Old style function declaration."),
01806 g_currentloc);
01807
01808 setGenericParamList (params);
01809 flipOldStyle = FALSE;
01810 g_expectingTypeName = TRUE;
01811 }
01812
01813 return (params);
01814 }
01815
01816 void
01817 doVaDcl ()
01818 {
01819 ctype c = ctype_unknown;
01820 cstring id = cstring_makeLiteral ("va_alist");
01821 uentry e;
01822
01823 if (ProcessingParams)
01824 {
01825 int i = uentryList_lookupRealName (saveParamList, id);
01826
01827 if (i >= 0)
01828 {
01829 e = uentry_makeVariableSrefParam (id, c, sRef_makeParam (i, c));
01830 }
01831 else
01832 {
01833 e = uentry_undefined;
01834 llfatalerrorLoc (cstring_makeLiteral ("va_dcl used without va_alist"));
01835 }
01836 }
01837 else
01838 {
01839 llerror (FLG_SYNTAX, cstring_makeLiteral ("va_dcl used outside of function declaration"));
01840 e = uentry_makeVariableLoc (id, c);
01841 }
01842
01843 cstring_free (id);
01844 uentry_setUsed (e, g_currentloc);
01845 usymtab_supEntrySref (e);
01846 }
01847
01848 sRef modListPointer (sRef s)
01849 {
01850 ctype ct = sRef_getType (s);
01851 ctype rt = ctype_realType (ct);
01852
01853 if (ctype_isAP (rt))
01854 {
01855 if (context_inHeader () && ctype_isAbstract (ct))
01856 {
01857 voptgenerror
01858 (FLG_ABSTRACT,
01859 message
01860 ("Modifies clause in header file dereferences abstract "
01861 "type %s (interface modifies clause should not depend "
01862 "on or expose type representation): %q",
01863 ctype_unparse (ct),
01864 sRef_unparse (s)),
01865 g_currentloc);
01866 }
01867
01868 return (sRef_constructPointer (s));
01869 }
01870 else
01871 {
01872 if (ctype_isKnown (rt))
01873 {
01874 voptgenerror
01875 (FLG_TYPE,
01876 message ("Implementation modifies clause dereferences non-pointer (type %s): %q",
01877 ctype_unparse (rt),
01878 sRef_unparse (s)),
01879 g_currentloc);
01880 }
01881
01882 return s;
01883 }
01884 }
01885
01886 sRef modListFieldAccess (sRef s, cstring f)
01887 {
01888 ctype ct = sRef_getType (s);
01889 ctype rt = ctype_realType (ct);
01890
01891 if (ctype_isStructorUnion (rt))
01892 {
01893 uentry tf = uentryList_lookupField (ctype_getFields (rt), f);
01894
01895 if (uentry_isUndefined (tf))
01896 {
01897 voptgenerror (FLG_TYPE,
01898 message ("Modifies list accesses non-existent "
01899 "field %s of %t: %q", f, ct,
01900 sRef_unparse (s)),
01901 g_currentloc);
01902
01903 cstring_free (f);
01904 return sRef_undefined;
01905 }
01906 else
01907 {
01908 if (ctype_isAbstract (ct) && context_inHeader ())
01909 {
01910 voptgenerror
01911 (FLG_ABSTRACT,
01912 message
01913 ("Modifies clause in header file accesses abstract "
01914 "type %s (interface modifies clause should not depend "
01915 "on or expose type representation): %q",
01916 ctype_unparse (ct),
01917 sRef_unparse (s)),
01918 g_currentloc);
01919 }
01920 }
01921
01922 cstring_markOwned (f);
01923 return (sRef_makeField (s, f));
01924 }
01925 else
01926 {
01927 voptgenerror
01928 (FLG_TYPE,
01929 message ("Modifies clause dereferences non-pointer (type %s): %q",
01930 ctype_unparse (rt),
01931 sRef_unparse (s)),
01932 g_currentloc);
01933
01934 cstring_free (f);
01935 return s;
01936 }
01937 }
01938
01939 sRef globListUnrecognized (cstring s)
01940 {
01941 if (cstring_equalLit (s, "nothing"))
01942 {
01943 return sRef_makeNothing ();
01944 }
01945 else if (cstring_equalLit (s, "internalState"))
01946 {
01947 return sRef_makeInternalState ();
01948 }
01949 else if (cstring_equalLit (s, "fileSystem")
01950 || cstring_equalLit (s, "systemState"))
01951 {
01952 return sRef_makeSystemState ();
01953 }
01954 else
01955 {
01956 voptgenerror
01957 (FLG_UNRECOG,
01958 message ("Unrecognized identifier in globals list: %s", s),
01959 g_currentloc);
01960
01961 return sRef_undefined;
01962 }
01963 }
01964
01965 sRef modListArrowAccess (sRef s, cstring f)
01966 {
01967 ctype ct = sRef_getType (s);
01968 ctype rt = ctype_realType (ct);
01969
01970 if (ctype_isRealPointer (rt))
01971 {
01972 ctype b = ctype_baseArrayPtr (rt);
01973 ctype rb = ctype_realType (b);
01974
01975 if (ctype_isStructorUnion (rb))
01976 {
01977 uentry tf = uentryList_lookupField (ctype_getFields (rb), f);
01978
01979 if (uentry_isUndefined (tf))
01980 {
01981 voptgenerror (FLG_TYPE,
01982 message ("Modifies list arrow accesses non-existent "
01983 "field %s of %t: %q", f, b,
01984 sRef_unparse (s)),
01985 g_currentloc);
01986
01987 cstring_free (f);
01988 return sRef_undefined;
01989 }
01990 else
01991 {
01992 if (context_inHeader ())
01993 {
01994 if (ctype_isAbstract (b))
01995 {
01996 voptgenerror
01997 (FLG_ABSTRACT,
01998 message
01999 ("Modifies clause in header file arrow accesses abstract "
02000 "type %s (interface modifies clause should not depend "
02001 "on or expose type representation): %q",
02002 ctype_unparse (b),
02003 sRef_unparse (s)),
02004 g_currentloc);
02005 }
02006 }
02007 else
02008 {
02009 if (ctype_isAbstract (ct))
02010 {
02011 voptgenerror
02012 (FLG_ABSTRACT,
02013 message
02014 ("Modifies clause in header file arrow accesses abstract "
02015 "type %s (interface modifies clause should not depend "
02016 "on or expose type representation): %q",
02017 ctype_unparse (ct),
02018 sRef_unparse (s)),
02019 g_currentloc);
02020 }
02021 }
02022 }
02023
02024 cstring_markOwned (f);
02025 return (sRef_makeArrow (s, f));
02026 }
02027 else
02028 {
02029 voptgenerror
02030 (FLG_TYPE,
02031 message ("Modifies clause arrow accesses pointer to "
02032 "non-structure (type %s): %q",
02033 ctype_unparse (rt),
02034 sRef_unparse (s)),
02035 g_currentloc);
02036 }
02037 }
02038 else
02039 {
02040 voptgenerror
02041 (FLG_TYPE,
02042 message ("Modifies clause arrow accesses non-pointer (type %s): %q",
02043 ctype_unparse (rt),
02044 sRef_unparse (s)),
02045 g_currentloc);
02046 }
02047
02048 cstring_free (f);
02049 return s;
02050 }
02051
02052 sRef checkSpecClausesId (uentry ue)
02053 {
02054 cstring s = uentry_rawName (ue);
02055
02056 if (sRef_isGlobal (uentry_getSref (ue)))
02057 {
02058 voptgenerror
02059 (FLG_SYNTAX,
02060 message ("Global variable %s used special clause. (Global variables "
02061 "are not recognized in special clauses. If there is "
02062 "sufficient interest in support for this, it may be "
02063 "added to a future release. Send mail to "
02064 "lclint@cs.virginia.edu.)",
02065 s),
02066 g_currentloc);
02067
02068 return sRef_undefined;
02069 }
02070 else
02071 {
02072 if (cstring_equalLit (s, "result"))
02073 {
02074 if (optgenerror
02075 (FLG_SYNTAX,
02076 message ("Special clause list uses %s which is a variable and has special "
02077 "meaning in a modifies list. (Special meaning assumed.)", s),
02078 g_currentloc))
02079 {
02080 uentry_showWhereDeclared (ue);
02081 }
02082 }
02083
02084 return uentry_getSref (ue);
02085 }
02086 }
02087
02088
02089 void checkModifiesId (uentry ue)
02090 {
02091 cstring s = uentry_rawName (ue);
02092
02093 if (cstring_equalLit (s, "nothing")
02094 || cstring_equalLit (s, "internalState")
02095 || cstring_equalLit (s, "systemState")
02096 || (cstring_equalLit (s, "fileSystem")))
02097 {
02098 if (optgenerror
02099 (FLG_SYNTAX,
02100 message ("Modifies list uses %s which is a variable and has special "
02101 "meaning in a modifies list. (Special meaning assumed.)", s),
02102 g_currentloc))
02103 {
02104 uentry_showWhereDeclared (ue);
02105 }
02106 }
02107 }
02108
02109 sRef fixModifiesId (cstring s)
02110 {
02111 sRef ret;
02112 cstring pname = makeParam (s);
02113 uentry ue = usymtab_lookupSafe (pname);
02114
02115 cstring_free (pname);
02116
02117 if (cstring_equalLit (s, "nothing"))
02118 {
02119 ret = sRef_makeNothing ();
02120 }
02121 else if (cstring_equalLit (s, "internalState"))
02122 {
02123 ret = sRef_makeInternalState ();
02124 }
02125 else if (cstring_equalLit (s, "fileSystem")
02126 || cstring_equalLit (s, "systemState"))
02127 {
02128 ret = sRef_makeSystemState ();
02129 }
02130 else
02131 {
02132 ret = sRef_undefined;
02133 }
02134
02135 if (sRef_isValid (ret))
02136 {
02137 if (uentry_isValid (ue))
02138 {
02139 voptgenerror
02140 (FLG_SYNTAX,
02141 message ("Modifies list uses %s which is a parameter and has special "
02142 "meaning in a modifies list. (Special meaning assumed.)", s),
02143 g_currentloc);
02144 }
02145 }
02146 else
02147 {
02148 if (uentry_isValid (ue))
02149 {
02150 ret = uentry_getSref (ue);
02151 }
02152 else
02153 {
02154 fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s));
02155 ret = sRef_undefined;
02156
02157 voptgenerror
02158 (FLG_UNRECOG,
02159 message ("Unrecognized identifier in modifies comment: %s", s),
02160 loc);
02161
02162 fileloc_free (loc);
02163 }
02164 }
02165
02166 return ret;
02167 }
02168
02169 sRef fixSpecClausesId (cstring s)
02170 {
02171 sRef ret;
02172 cstring pname = makeParam (s);
02173 uentry ue = usymtab_lookupSafe (pname);
02174
02175 cstring_free (pname);
02176
02177 if (cstring_equalLit (s, "result"))
02178 {
02179 ret = sRef_makeResult ();
02180 }
02181 else
02182 {
02183 ret = sRef_undefined;
02184 }
02185
02186 if (sRef_isValid (ret))
02187 {
02188 if (uentry_isValid (ue))
02189 {
02190 voptgenerror
02191 (FLG_SYNTAX,
02192 message ("Special clause uses %s which is a parameter and has special "
02193 "meaning in a special clause. (Special meaning assumed.)", s),
02194 g_currentloc);
02195 }
02196 }
02197 else
02198 {
02199 if (uentry_isValid (ue))
02200 {
02201 ret = uentry_getSref (ue);
02202
02203 if (sRef_isGlobal (ret))
02204 {
02205 voptgenerror
02206 (FLG_SYNTAX,
02207 message ("Global variable %s used special clause. (Global variables "
02208 "are not recognized in special clauses. If there is "
02209 "sufficient interest in support for this, it may be "
02210 "added to a future release. Send mail to "
02211 "lclint@cs.virginia.edu.)",
02212 s),
02213 g_currentloc);
02214
02215 ret = sRef_undefined;
02216 }
02217 }
02218 else
02219 {
02220 fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s));
02221 ret = sRef_undefined;
02222
02223 voptgenerror
02224 (FLG_UNRECOG,
02225 message ("Unrecognized identifier in special clause: %s", s),
02226 loc);
02227
02228 fileloc_free (loc);
02229 }
02230 }
02231
02232 return ret;
02233 }
02234
02235 sRef modListArrayFetch (sRef s, sRef mexp)
02236 {
02237 ctype ct = sRef_getType (s);
02238 ctype rt = ctype_realType (ct);
02239
02240 if (ctype_isAP (rt))
02241 {
02242 if (context_inHeader () && ctype_isAbstract (ct))
02243 {
02244 voptgenerror
02245 (FLG_ABSTRACT,
02246 message
02247 ("Modifies clause in header file indexes abstract "
02248 "type %s (interface modifies clause should not depend "
02249 "on or expose type representation): %q",
02250 ctype_unparse (ct),
02251 sRef_unparse (s)),
02252 g_currentloc);
02253 }
02254
02255 return (sRef_makeAnyArrayFetch (s));
02256 }
02257 else
02258 {
02259 voptgenerror
02260 (FLG_TYPE,
02261 message
02262 ("Implementation modifies clause uses array fetch on non-array (type %s): %q",
02263 ctype_unparse (ct), sRef_unparse (s)),
02264 g_currentloc);
02265 return s;
02266 }
02267 }
02268
02269
02270
02271
02272
02273
02274
02275