Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

varKinds.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** varKinds.c
00026 */
00027 
00028 # include "lclintMacros.nf"
00029 # include "basic.h"
00030 
00031 alkind alkind_fromInt (int n)
00032 {
00033   /*@+enumint@*/
00034   llassert (n >= AK_UNKNOWN && n <= AK_LOCAL);
00035   /*@=enumint@*/
00036 
00037   return ((alkind)n);
00038 }
00039 
00040 nstate nstate_fromInt (int n)
00041 {
00042   /*@+enumint@*/
00043   llassert (n >= NS_ERROR && n <= NS_ABSNULL);
00044   /*@=enumint@*/
00045 
00046   return ((nstate)n);
00047 }
00048 
00049 sstate sstate_fromInt (int n)
00050 {
00051   /*@+enumint@*/
00052   llassert (n >= SS_UNKNOWN && n < SS_LAST);
00053   /*@=enumint@*/
00054 
00055   return ((sstate)n);
00056 }
00057 
00058 exkind exkind_fromInt (int n)
00059 {
00060   /*@+enumint@*/
00061   llassert (n >= XO_UNKNOWN && n <= XO_OBSERVER);
00062   /*@=enumint@*/
00063 
00064   return ((exkind) n);
00065 }
00066 
00067 cstring sstate_unparse (sstate s)
00068 {
00069   switch (s)
00070     {
00071     case SS_UNKNOWN:   return cstring_makeLiteralTemp ("unknown");
00072     case SS_UNUSEABLE: return cstring_makeLiteralTemp ("unuseable");
00073     case SS_UNDEFINED: return cstring_makeLiteralTemp ("undefined");
00074     case SS_MUNDEFINED:return cstring_makeLiteralTemp ("possibly undefined");
00075     case SS_ALLOCATED: return cstring_makeLiteralTemp ("allocated");
00076     case SS_PDEFINED:  return cstring_makeLiteralTemp ("partially defined");
00077     case SS_DEFINED:   return cstring_makeLiteralTemp ("defined");
00078     case SS_PARTIAL:   return cstring_makeLiteralTemp ("partial");
00079     case SS_SPECIAL:   return cstring_makeLiteralTemp ("special");
00080     case SS_DEAD:      return cstring_makeLiteralTemp ("dead");
00081     case SS_HOFFA:     return cstring_makeLiteralTemp ("probably dead");
00082     case SS_FIXED:     return cstring_makeLiteralTemp ("unmodifiable");
00083     case SS_RELDEF:    return cstring_makeLiteralTemp ("reldef");
00084     case SS_LAST:      llcontbuglit ("sstate_unparse: last");
00085                        return cstring_makeLiteralTemp ("<error>");
00086     case SS_UNDEFGLOB:     return cstring_makeLiteralTemp ("undefglob");
00087     case SS_KILLED:    return cstring_makeLiteralTemp ("killed");
00088     case SS_UNDEFKILLED:
00089       return cstring_makeLiteralTemp ("undefkilled");
00090     }
00091 
00092   BADEXIT;
00093 }
00094 
00095 bool nstate_possiblyNull (nstate n)
00096 {
00097   /*
00098   ** note: not NS_UNKNOWN or NS_ERROR 
00099   */
00100 
00101   return ((n >= NS_CONSTNULL) && (n <= NS_ABSNULL));
00102 }
00103 
00104 bool nstate_perhapsNull (nstate n)
00105 {
00106   /*
00107   ** note: not NS_UNKNOWN or NS_ERROR 
00108   */
00109 
00110   return ((n >= NS_RELNULL) && (n <= NS_ABSNULL));
00111 }
00112 
00113 cstring nstate_unparse (nstate n)
00114 {
00115   switch (n)
00116     {
00117     case NS_ERROR:     return cstring_makeLiteralTemp ("<null error>");
00118     case NS_UNKNOWN:   return cstring_makeLiteralTemp ("implicitly non-null");
00119     case NS_POSNULL:   return cstring_makeLiteralTemp ("null");
00120     case NS_DEFNULL:   return cstring_makeLiteralTemp ("null");
00121     case NS_NOTNULL:   return cstring_makeLiteralTemp ("notnull");
00122     case NS_MNOTNULL:  return cstring_makeLiteralTemp ("notnull");
00123     case NS_ABSNULL:   return cstring_makeLiteralTemp ("null");
00124     case NS_RELNULL:   return cstring_makeLiteralTemp ("relnull");
00125     case NS_CONSTNULL: return cstring_makeLiteralTemp ("null");
00126     }
00127 
00128   BADEXIT;
00129 }
00130 
00131 /*
00132 ** ??? (used to do something different for guarded)
00133 */
00134 
00135 int nstate_compare (nstate n1, nstate n2)
00136 {
00137   return (generic_compare (n1, n2));
00138 }
00139 
00140 /*
00141 ** This occurs when we select a field with alkind inner, 
00142 ** from a structure with alkind outer.  It is probably
00143 ** unnecessary.
00144 */
00145 
00146 alkind alkind_derive (alkind outer, alkind inner)
00147 {
00148   switch (outer)
00149     {
00150     case AK_ERROR:
00151     case AK_UNKNOWN: return inner;
00152     case AK_KEPT:
00153     case AK_KEEP:
00154     case AK_ONLY: 
00155     case AK_IMPONLY:
00156     case AK_OWNED:
00157     case AK_IMPDEPENDENT:
00158     case AK_DEPENDENT:
00159       if (inner == AK_SHARED) return AK_SHARED;
00160       else return outer;
00161       /* not so sure about these? */
00162     case AK_REFCOUNTED:
00163     case AK_NEWREF:
00164     case AK_KILLREF:
00165     case AK_REFS:
00166     case AK_STACK:
00167     case AK_STATIC:
00168       return outer;
00169     case AK_TEMP: 
00170     case AK_IMPTEMP:
00171     case AK_SHARED:
00172     case AK_UNIQUE:
00173     case AK_LOCAL: 
00174     case AK_FRESH:
00175     case AK_RETURNED:
00176       if (alkind_isKnown (inner)) return inner; 
00177       else return outer;
00178     }
00179   BADEXIT;
00180 }
00181 
00182 cstring alkind_unparse (alkind a)
00183 {
00184   switch (a)
00185     {
00186     case AK_ERROR:           return cstring_makeLiteralTemp ("<error>");
00187     case AK_UNKNOWN:         return cstring_makeLiteralTemp ("unqualified");
00188     case AK_ONLY:            return cstring_makeLiteralTemp ("only");
00189     case AK_IMPONLY:         return cstring_makeLiteralTemp ("implicitly only");
00190     case AK_OWNED:           return cstring_makeLiteralTemp ("owned");
00191     case AK_IMPDEPENDENT:    return cstring_makeLiteralTemp ("implicitly dependent");
00192     case AK_DEPENDENT:       return cstring_makeLiteralTemp ("dependent");
00193     case AK_KEEP:            return cstring_makeLiteralTemp ("keep");
00194     case AK_KEPT:            return cstring_makeLiteralTemp ("kept");
00195     case AK_IMPTEMP:         return cstring_makeLiteralTemp ("implicitly temp");
00196     case AK_TEMP:            return cstring_makeLiteralTemp ("temp");
00197     case AK_SHARED:          return cstring_makeLiteralTemp ("shared");
00198     case AK_UNIQUE:          return cstring_makeLiteralTemp ("unique");
00199     case AK_RETURNED:        return cstring_makeLiteralTemp ("returned");
00200     case AK_FRESH:           return cstring_makeLiteralTemp ("fresh");
00201     case AK_STACK:           return cstring_makeLiteralTemp ("stack");
00202     case AK_REFCOUNTED:      return cstring_makeLiteralTemp ("refcounted");
00203     case AK_REFS:            return cstring_makeLiteralTemp ("refs");
00204     case AK_KILLREF:         return cstring_makeLiteralTemp ("killref");
00205     case AK_NEWREF:          return cstring_makeLiteralTemp ("newref");
00206     case AK_LOCAL:           return cstring_makeLiteralTemp ("local");
00207     case AK_STATIC:          return cstring_makeLiteralTemp ("unqualified static");
00208     }
00209     BADEXIT;
00210 }
00211 
00212 cstring exkind_unparse (exkind a)
00213 {
00214   switch (a)
00215     {
00216     case XO_UNKNOWN:         return cstring_makeLiteralTemp ("unknown");
00217     case XO_NORMAL:          return cstring_makeLiteralTemp ("unexposed");
00218     case XO_EXPOSED:         return cstring_makeLiteralTemp ("exposed");
00219     case XO_OBSERVER:        return cstring_makeLiteralTemp ("observer");
00220     }
00221   BADEXIT;
00222 }
00223 
00224 cstring exkind_capName (exkind a)
00225 {
00226   switch (a)
00227     {
00228     case XO_UNKNOWN:         return cstring_makeLiteralTemp ("Unknown");
00229     case XO_NORMAL:          return cstring_makeLiteralTemp ("Unexposed");
00230     case XO_EXPOSED:         return cstring_makeLiteralTemp ("Exposed");
00231     case XO_OBSERVER:        return cstring_makeLiteralTemp ("Observer");
00232     }
00233   BADEXIT;
00234 }
00235 
00236 cstring exkind_unparseError (exkind a)
00237 {
00238   switch (a)
00239     {
00240     case XO_UNKNOWN:         return cstring_makeLiteralTemp ("unqualified");
00241     case XO_NORMAL:          return cstring_makeLiteralTemp ("unqualifier");
00242     case XO_EXPOSED:         return cstring_makeLiteralTemp ("exposed");
00243     case XO_OBSERVER:        return cstring_makeLiteralTemp ("observer");
00244     }
00245   BADEXIT;
00246 }
00247 
00248 cstring alkind_capName (alkind a)
00249 {
00250   switch (a)
00251     {
00252     case AK_ERROR:    
00253       return cstring_makeLiteralTemp ("<Error>");
00254     case AK_UNKNOWN:     
00255       return cstring_makeLiteralTemp ("Unqualified");
00256     case AK_ONLY:  
00257       return cstring_makeLiteralTemp ("Only");
00258     case AK_IMPONLY:
00259       return cstring_makeLiteralTemp ("Implicitly only");
00260     case AK_OWNED:
00261       return cstring_makeLiteralTemp ("Owned");
00262     case AK_IMPDEPENDENT:  
00263       return cstring_makeLiteralTemp ("Implicitly dependent");
00264     case AK_DEPENDENT:  
00265       return cstring_makeLiteralTemp ("Dependent");
00266     case AK_KEEP:     
00267       return cstring_makeLiteralTemp ("Keep");
00268     case AK_KEPT:    
00269       return cstring_makeLiteralTemp ("Kept");
00270     case AK_IMPTEMP:   
00271       return cstring_makeLiteralTemp ("Implicitly temp");
00272     case AK_TEMP:    
00273       return cstring_makeLiteralTemp ("Temp");
00274     case AK_SHARED:
00275       return cstring_makeLiteralTemp ("Shared");
00276     case AK_UNIQUE:    
00277       return cstring_makeLiteralTemp ("Unique");
00278     case AK_RETURNED:
00279       return cstring_makeLiteralTemp ("Returned");
00280     case AK_FRESH:   
00281       return cstring_makeLiteralTemp ("Fresh");
00282     case AK_STACK:      
00283       return cstring_makeLiteralTemp ("Stack");
00284     case AK_REFCOUNTED: 
00285       return cstring_makeLiteralTemp ("Refcounted");
00286     case AK_REFS:
00287       return cstring_makeLiteralTemp ("Refs");
00288     case AK_KILLREF: 
00289       return cstring_makeLiteralTemp ("Killref");
00290     case AK_NEWREF:    
00291       return cstring_makeLiteralTemp ("Newref");
00292     case AK_LOCAL:    
00293       return cstring_makeLiteralTemp ("Local");
00294     case AK_STATIC: 
00295       return cstring_makeLiteralTemp ("Unqualified static");
00296     }
00297   BADEXIT;
00298 }
00299 
00300 exkind
00301 exkind_fromQual (qual q)
00302 {
00303   if (qual_isExposed (q))     return XO_EXPOSED;
00304   if (qual_isObserver (q))    return XO_OBSERVER;
00305   else
00306     {
00307       llcontbug (message ("exkind_fromQual: not exp qualifier: %d" , (int)q));
00308       return XO_UNKNOWN;
00309     }
00310 }
00311 
00312 sstate
00313 sstate_fromQual (qual q)
00314 {
00315   if (qual_isOut (q))          return SS_ALLOCATED;
00316   if (qual_isIn (q))           return SS_DEFINED;
00317   else if (qual_isPartial (q)) return SS_PARTIAL;
00318   else if (qual_isRelDef (q))  return SS_RELDEF;
00319   else if (qual_isUndef (q))   return SS_UNDEFGLOB;
00320   else if (qual_isKilled (q))  return SS_KILLED;
00321   else if (qual_isSpecial (q)) return SS_SPECIAL;
00322   else
00323     {
00324       llcontbug (message ("sstate_fromQual: not alias qualifier: %s (%d)" , 
00325                           qual_unparse (q),
00326                           (int)q));
00327       return SS_UNKNOWN;
00328     }
00329 }
00330 
00331 exitkind
00332 exitkind_fromQual (qual q)
00333 {
00334   if (qual_isExits (q))     return XK_MUSTEXIT;
00335   if (qual_isMayExit (q))   return XK_MAYEXIT;
00336   if (qual_isTrueExit (q))  return XK_TRUEEXIT;
00337   if (qual_isFalseExit (q)) return XK_FALSEEXIT;
00338   if (qual_isNeverExit (q)) return XK_NEVERESCAPE;
00339   else
00340     {
00341       llcontbug (message ("exitkind_fromQual: not exit qualifier: %s",
00342                           qual_unparse (q)));
00343       return XK_UNKNOWN;
00344     }
00345 }
00346 
00347 alkind
00348 alkind_fromQual (qual q)
00349 {
00350   if (qual_isOnly (q))       return AK_ONLY;
00351   if (qual_isImpOnly (q))    return AK_IMPONLY;
00352   if (qual_isKeep (q))       return AK_KEEP;
00353   if (qual_isKept (q))       return AK_KEPT;
00354   if (qual_isTemp (q))       return AK_TEMP;
00355   if (qual_isShared (q))     return AK_SHARED;
00356   if (qual_isUnique (q))     return AK_UNIQUE;
00357   if (qual_isRefCounted (q)) return AK_REFCOUNTED;
00358   if (qual_isRefs (q))       return AK_REFS;
00359   if (qual_isNewRef (q))     return AK_NEWREF;
00360   if (qual_isKillRef (q))    return AK_KILLREF;
00361   if (qual_isTempRef (q))    return AK_KILLREF; /* kludge? use kill ref for this */
00362   if (qual_isOwned (q))      return AK_OWNED;
00363   if (qual_isDependent (q))  return AK_DEPENDENT;
00364 
00365   llcontbug (message ("alkind_fromQual: not alias qualifier: %d" , (int)q));
00366   return AK_ERROR;
00367 }    
00368 
00369 static bool alkind_isMeaningless (alkind a1)
00370 {
00371   return (a1 == AK_ERROR || a1 == AK_UNKNOWN || a1 == AK_RETURNED
00372           || a1 == AK_STACK || a1 == AK_REFCOUNTED
00373           || a1 == AK_REFS || a1 == AK_KILLREF || a1 == AK_NEWREF
00374           || a1 == AK_LOCAL);
00375 }
00376 
00377 bool alkind_compatible (alkind a1, alkind a2)
00378 {
00379   if (a1 == a2) return TRUE;
00380   if (a2 == AK_ERROR) return TRUE;
00381   if (a2 == AK_UNKNOWN)
00382     {
00383       return (alkind_isMeaningless (a1) || (a1 == AK_IMPTEMP));
00384     }
00385 
00386   switch (a1)
00387     {
00388     case AK_ERROR:               return TRUE;
00389     case AK_UNKNOWN:             return (alkind_isMeaningless (a2)
00390                                          || (a2 == AK_IMPTEMP));
00391     case AK_IMPONLY:             return (a2 == AK_KEEP || a2 == AK_FRESH 
00392                                          || a2 == AK_ONLY);
00393     case AK_ONLY:                return (a2 == AK_KEEP || a2 == AK_FRESH
00394                                          || a2 == AK_IMPONLY);
00395     case AK_OWNED:               return FALSE;
00396     case AK_IMPDEPENDENT:        return (a2 == AK_DEPENDENT);
00397     case AK_DEPENDENT:           return (a2 == AK_IMPDEPENDENT);
00398     case AK_KEEP:                return (a2 == AK_ONLY || a2 == AK_FRESH
00399                                          || a2 == AK_IMPONLY);
00400     case AK_KEPT:                return FALSE;
00401     case AK_IMPTEMP:             return (a2 == AK_TEMP);
00402     case AK_TEMP:                return (a2 == AK_IMPTEMP);
00403     case AK_SHARED:              return FALSE;
00404     case AK_UNIQUE:              return (a2 == AK_TEMP);
00405     case AK_RETURNED:            return (alkind_isMeaningless (a2));
00406     case AK_FRESH:               return (alkind_isOnly (a2));
00407     case AK_STACK:               return (alkind_isMeaningless (a2));
00408     case AK_REFCOUNTED:          return (alkind_isMeaningless (a2));
00409     case AK_REFS:                return (alkind_isMeaningless (a2));
00410     case AK_KILLREF:             return (alkind_isMeaningless (a2));
00411     case AK_NEWREF:              return (alkind_isMeaningless (a2));
00412     case AK_LOCAL:               return (alkind_isMeaningless (a2));
00413     case AK_STATIC:              return (alkind_isMeaningless (a2));
00414     }
00415   BADEXIT;
00416 }
00417 
00418 bool alkind_equal (alkind a1, alkind a2)
00419 {
00420   if (a1 == a2) return TRUE;
00421   if (a2 == AK_ERROR) return TRUE;
00422 
00423   switch (a1)
00424     {
00425     case AK_ERROR:               return TRUE;
00426     case AK_IMPONLY:             return (a2 == AK_ONLY);
00427     case AK_ONLY:                return (a2 == AK_IMPONLY);
00428     case AK_IMPDEPENDENT:        return (a2 == AK_DEPENDENT);
00429     case AK_DEPENDENT:           return (a2 == AK_IMPDEPENDENT);
00430     case AK_IMPTEMP:             return (a2 == AK_TEMP);
00431     case AK_TEMP:                return (a2 == AK_IMPTEMP);
00432     default:                     return FALSE;
00433     }
00434 
00435   BADEXIT;
00436 }
00437 
00438 alkind
00439 alkind_fixImplicit (alkind a)
00440 {
00441   if (a == AK_IMPTEMP) return AK_TEMP;
00442   if (a == AK_IMPONLY) return AK_IMPONLY;
00443   if (a == AK_IMPDEPENDENT) return AK_DEPENDENT;
00444 
00445   return a;
00446 }
00447 
00448 cstring exitkind_unparse (exitkind k)
00449 {
00450   switch (k)
00451     {
00452     case XK_ERROR:       return (cstring_makeLiteralTemp ("<error>"));
00453     case XK_UNKNOWN:     return (cstring_makeLiteralTemp ("?"));
00454     case XK_NEVERESCAPE: return (cstring_makeLiteralTemp ("never escape"));
00455     case XK_MAYEXIT:     return (cstring_makeLiteralTemp ("mayexit"));
00456     case XK_MUSTEXIT:    return (cstring_makeLiteralTemp ("exits"));
00457     case XK_TRUEEXIT:    return (cstring_makeLiteralTemp ("trueexit"));
00458     case XK_FALSEEXIT:   return (cstring_makeLiteralTemp ("falseexit"));
00459     case XK_MUSTRETURN:  return (cstring_makeLiteralTemp ("mustreturn"));
00460     case XK_MAYRETURN:   return (cstring_makeLiteralTemp ("mayreturn"));
00461     case XK_MUSTRETURNEXIT: return (cstring_makeLiteralTemp ("mustreturnexit"));
00462     case XK_MAYRETURNEXIT: return (cstring_makeLiteralTemp ("mayreturnexit"));
00463     case XK_GOTO:        return (cstring_makeLiteralTemp ("goto"));
00464     case XK_MAYGOTO:     return (cstring_makeLiteralTemp ("maygoto"));
00465     }
00466   
00467  BADEXIT;
00468 }
00469 
00470 exitkind exitkind_makeConditional (exitkind k)
00471 {
00472   switch (k)
00473     {
00474     case XK_TRUEEXIT:
00475     case XK_FALSEEXIT: 
00476     case XK_MUSTEXIT:       return XK_MAYEXIT;
00477     case XK_MUSTRETURN:     return XK_MAYRETURN;
00478     case XK_MUSTRETURNEXIT: return XK_MAYRETURNEXIT;
00479     case XK_GOTO:           return XK_MAYGOTO;
00480     default:                return k;
00481     }
00482 }
00483 
00484 exitkind exitkind_combine (exitkind k1, exitkind k2)
00485 {
00486   if (k1 == k2)
00487     {
00488       return k1;
00489     }
00490 
00491   if (k2 == XK_ERROR)
00492     {
00493       return XK_ERROR;
00494     }
00495 
00496   switch (k1)
00497     {
00498     case XK_ERROR: return XK_ERROR;
00499     case XK_UNKNOWN:     
00500     case XK_NEVERESCAPE: return (exitkind_makeConditional (k2));
00501     case XK_MUSTEXIT:    
00502       switch (k2)
00503         {
00504         case XK_MUSTRETURNEXIT:
00505         case XK_MUSTRETURN: return XK_MUSTRETURNEXIT;
00506         case XK_MAYRETURNEXIT:
00507         case XK_MAYRETURN:  return XK_MAYRETURNEXIT;
00508         default:             return XK_MAYEXIT;
00509         }
00510       BADEXIT;
00511 
00512     case XK_MAYEXIT:     
00513     case XK_TRUEEXIT:    
00514     case XK_FALSEEXIT:   
00515       switch (k2)
00516         {
00517         case XK_MUSTRETURNEXIT:
00518         case XK_MAYRETURNEXIT:
00519         case XK_MAYRETURN:
00520         case XK_MUSTRETURN: return XK_MAYRETURNEXIT;
00521         default:             return XK_MAYEXIT;
00522         }
00523       BADEXIT;
00524 
00525     case XK_MUSTRETURN:
00526       switch (k2)
00527         {
00528         case XK_MUSTRETURNEXIT:
00529         case XK_MUSTEXIT:    return XK_MUSTRETURNEXIT;
00530         case XK_MAYRETURNEXIT:
00531         case XK_TRUEEXIT:
00532         case XK_FALSEEXIT:
00533         case XK_MAYEXIT:     return XK_MAYRETURNEXIT;
00534         default:              return XK_MAYRETURN;
00535         }
00536       BADEXIT;
00537 
00538     case XK_MAYRETURN:
00539       if (exitkind_couldExit (k2))
00540         {
00541           return XK_MAYRETURNEXIT;
00542         }
00543       else
00544         {
00545           return XK_MAYRETURN;
00546         }
00547 
00548     case XK_MUSTRETURNEXIT: 
00549       switch (k2)
00550         {
00551         case XK_MUSTRETURN:
00552         case XK_MUSTEXIT:    return XK_MUSTRETURNEXIT;
00553         default:              return XK_MAYRETURNEXIT;
00554         }
00555       BADEXIT;
00556 
00557     case XK_MAYRETURNEXIT:   return XK_MAYRETURNEXIT;
00558     case XK_GOTO:
00559     case XK_MAYGOTO:         
00560       if (exitkind_couldExit (k2))
00561         {
00562           return XK_MAYRETURNEXIT;
00563         }
00564       return XK_MAYGOTO;
00565     }
00566   
00567  BADEXIT;
00568 }
00569 
00570 bool exitkind_couldExit (exitkind e)
00571 {
00572   switch (e)
00573     {
00574     case XK_MAYEXIT:
00575     case XK_MUSTEXIT:
00576     case XK_TRUEEXIT:
00577     case XK_FALSEEXIT:
00578     case XK_MAYRETURNEXIT:
00579     case XK_MUSTRETURNEXIT: 
00580     case XK_GOTO:
00581     case XK_MAYGOTO: return TRUE;
00582     default: return FALSE;
00583     }
00584 }
00585 
00586 static bool exitkind_couldReturn (exitkind e) /*@*/ 
00587 {
00588   switch (e)
00589     {
00590     case XK_MUSTRETURN:
00591     case XK_MAYRETURN:
00592     case XK_MAYRETURNEXIT:
00593     case XK_MUSTRETURNEXIT:  return TRUE;
00594     default: return FALSE;
00595     }
00596 }
00597 
00598 static bool exitkind_couldGoto (exitkind e) /*@*/
00599 {
00600   return (e == XK_GOTO || e == XK_MAYGOTO);
00601 }
00602 
00603 bool exitkind_couldEscape (exitkind e)
00604 {
00605   return exitkind_couldReturn (e) || exitkind_couldExit (e)
00606     || exitkind_couldGoto (e);
00607 }
00608 
00609 exitkind exitkind_fromInt (int x)
00610 {
00611   /*@+enumint@*/
00612   llassert (x >= XK_ERROR && x <= XK_LAST);
00613   /*@=enumint@*/
00614 
00615   return (exitkind) x;
00616 }
00617 
00618 
00619 
00620 
00621 
00622 
00623 

Generated at Fri Nov 3 18:57:46 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000