2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
31 # include "lclintMacros.nf"
33 # include "cgrammar.h"
36 # include "usymtab_interface.h"
39 # include "structNames.h"
40 # include "nameChecks.h"
43 # include "sgrammar_tokens.h"
45 # include "cgrammar_tokens.h"
49 ** Lots of variables are needed because of interactions with the
50 ** parser. This is easier than restructuring the grammar so the
51 ** right values are available in the right place.
55 /*@only@*/ static constraintList fcnConstraints = NULL;
57 /*@only@*/ static constraintList fcnEnsuresConstraints = NULL;
61 static /*@only@*/ constraintList implicitFcnConstraints = NULL;
64 //static constraintList fcnPreConditions = NULL;
66 static void clabstract_prepareFunction (uentry p_e) /*@modifies p_e@*/ ;
67 static bool fcnNoGlobals = FALSE;
68 static bool ProcessingVars = FALSE;
69 static bool ProcessingParams = FALSE;
70 static bool ProcessingGlobals = FALSE;
71 static bool ProcessingTypedef = FALSE;
72 static bool ProcessingIterVars = FALSE;
73 static /*@only@*/ qtype processingType = qtype_undefined;
74 static uentry currentIter = uentry_undefined;
75 static /*@dependent@*/ uentryList saveParamList; /* for old style functions */
76 static /*@owned@*/ uentry saveFunction = uentry_undefined;
77 static int saveIterParamNo;
78 static idDecl fixStructDecl (/*@returned@*/ idDecl p_d);
79 static void checkTypeDecl (uentry p_e, ctype p_rep);
80 static /*@dependent@*/ fileloc saveStoreLoc = fileloc_undefined;
81 static storageClassCode storageClass = SCNONE;
82 static void declareEnumList (/*@temp@*/ enumNameList p_el, ctype p_c, fileloc p_loc);
83 static void resetGlobals (void);
84 static /*@null@*/ qual specialFunctionCode;
85 static bool argsUsed = FALSE;
87 extern void clabstract_initMod ()
89 specialFunctionCode = qual_createUnknown ();
90 DPRINTF (("Initialized: %s", qual_unparse (specialFunctionCode)));
93 static bool hasSpecialCode (void)
95 return (!qual_isUnknown (specialFunctionCode));
98 extern void setArgsUsed (void)
104 cstring_makeLiteral ("Multiple ARGSUSED comments for one function"),
111 static void reflectArgsUsed (uentry ue)
115 if (uentry_isFunction (ue))
117 uentryList params = uentry_getParams (ue);
119 uentryList_elements (params, el)
121 uentry_setUsed (el, fileloc_undefined);
122 } end_uentryList_elements ;
129 extern void setSpecialFunction (qual qu)
131 if (!qual_isUnknown (specialFunctionCode))
133 voptgenerror (FLG_SYNTAX,
134 message ("Multiple special function codes: %s, %s "
135 "(first code is ignored)",
136 qual_unparse (specialFunctionCode),
141 specialFunctionCode = qu;
144 static void reflectSpecialCode (uentry ue)
146 if (qual_isUnknown (specialFunctionCode)) {
148 } else if (qual_isPrintfLike (specialFunctionCode)) {
149 uentry_setPrintfLike (ue);
150 } else if (qual_isScanfLike (specialFunctionCode)) {
151 uentry_setScanfLike (ue);
152 } else if (qual_isMessageLike (specialFunctionCode)) {
153 uentry_setMessageLike (ue);
158 specialFunctionCode = qual_createUnknown ();
161 static void resetStorageClass (void)
163 qtype_free (processingType);
164 processingType = qtype_undefined;
165 storageClass = SCNONE;
169 used to be reflectModGlobs
170 changed to reflectBufferConstraint
171 and removed buffer constraint stuff
172 to merge with other code tree.
175 static void reflectBufferConstraint (uentry ue)
178 if ( constraintList_isDefined(fcnConstraints) )
180 uentry_setPreconditions (ue, fcnConstraints);
181 fcnConstraints = constraintList_undefined;
184 if ( constraintList_isDefined(fcnEnsuresConstraints) )
186 uentry_setPostconditions (ue, fcnEnsuresConstraints);
187 fcnEnsuresConstraints = constraintList_undefined;
192 static void reflectStorageClass (uentry u)
194 if (storageClass == SCSTATIC)
196 uentry_setStatic (u);
198 else if (storageClass == SCEXTERN)
200 uentry_setExtern (u);
204 ; /* no storage class */
211 saveStoreLoc = g_currentloc;
214 void setFunctionNoGlobals (void)
221 constraintList getFunctionConstraints (void)
223 return constraintList_copy (fcnConstraints);
227 constraintList getEnsuresConstraints (void)
229 return constraintList_copy (fcnEnsuresConstraints);
232 void setEnsuresConstraints (constraintList c)
234 if (constraintList_isDefined(fcnEnsuresConstraints) )
235 constraintList_free(fcnEnsuresConstraints);
237 DPRINTF(( message("Setting ensures constraints to %q",
238 constraintList_print(c) ) ));
240 fcnEnsuresConstraints = constraintList_copy (c);
243 void setFunctionConstraints (constraintList c)
245 if (constraintList_isDefined(fcnConstraints) )
246 constraintList_free(fcnConstraints);
248 DPRINTF(( message("Setting requires constraints to %q",
249 constraintList_print(c) ) ));
252 fcnConstraints = constraintList_copy (c);
256 static void reflectGlobalQualifiers (sRef sr, qualList quals)
258 DPRINTF (("Reflect global qualifiers: %s / %s",
259 sRef_unparseFull (sr), qualList_unparse (quals)));
261 qualList_elements (quals, qel)
263 if (qual_isGlobalQual (qel)) /* undef, killed */
265 sstate oldstate = sRef_getDefState (sr);
266 sstate defstate = sstate_fromQual (qel);
268 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
269 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
271 defstate = SS_UNDEFKILLED;
278 sRef_setDefState (sr, defstate, fileloc_undefined);
279 DPRINTF (("State: %s", sRef_unparseFull (sr)));
281 else if (qual_isAllocQual (qel)) /* out, partial, reldef, etc. */
283 ctype realType = sRef_getType (sr);
284 sstate defstate = sstate_fromQual (qel);
286 if (qual_isRelDef (qel))
288 ; /* okay anywhere */
292 if (!ctype_isAP (realType)
293 && !ctype_isSU (realType)
294 && !ctype_isUnknown (realType)
295 && !ctype_isAbstract (sRef_getType (sr)))
299 message ("Qualifier %s used on non-pointer or struct: %q",
300 qual_unparse (qel), sRef_unparse (sr)));
305 sRef_setDefState (sr, defstate, fileloc_undefined);
307 else if (qual_isNull (qel))
309 sRef_setNullState (sr, NS_POSNULL, fileloc_undefined);
311 else if (qual_isRelNull (qel))
313 sRef_setNullState (sr, NS_RELNULL, fileloc_undefined);
315 else if (qual_isNotNull (qel))
317 sRef_setNullState (sr, NS_MNOTNULL, fileloc_undefined);
321 if (qual_isCQual (qel))
328 message ("Qualifier %s cannot be used in a globals list",
329 qual_unparse (qel)));
332 } end_qualList_elements;
335 sRef clabstract_createGlobal (sRef sr, qualList quals)
339 if (sRef_isValid (sr))
341 res = sRef_copy (sr);
342 DPRINTF (("Reflecting quals: %s / %s", sRef_unparse (sr), qualList_unparse (quals)));
343 reflectGlobalQualifiers (res, quals);
344 DPRINTF (("==> %s", sRef_unparseFull (res)));
348 res = sRef_undefined;
351 qualList_free (quals);
355 extern void declareCIter (cstring name, /*@owned@*/ uentryList params)
359 ue = uentry_makeIter (name,
360 ctype_makeFunction (ctype_void, params),
361 fileloc_copy (g_currentloc));
363 usymtab_supEntry (uentry_makeEndIter (name, fileloc_copy (g_currentloc)));
365 reflectBufferConstraint (ue);
367 ue = usymtab_supGlobalEntryReturn (ue);
370 extern void nextIterParam (void)
372 llassert (ProcessingIterVars);
376 extern int iterParamNo (void)
378 llassert (ProcessingIterVars);
379 return saveIterParamNo;
383 ** yucky hacks to put it in the right place
387 makeCurrentParam (idDecl t)
391 saveStoreLoc = fileloc_undefined;
393 /* param number unknown */
395 ue = uentry_makeParam (t, 0);
400 declareUnnamedEnum (enumNameList el)
402 ctype ret = usymtab_enumEnumNameListType (el);
406 if (ctype_isDefined (ret))
409 e = uentry_makeEnumTagLoc (ctype_enumTag (rt), ret);
411 reflectStorageClass (e);
412 usymtab_supGlobalEntry (e);
414 declareEnumList (el, ret, g_currentloc);
415 enumNameList_free (el);
419 ctype ct = ctype_createEnum (fakeTag (), el);
421 e = uentry_makeEnumTagLoc (ctype_enumTag (ctype_realType (ct)), ct);
422 reflectStorageClass (e);
424 e = usymtab_supGlobalEntryReturn (e);
425 rt = uentry_getAbstractType (e);
426 declareEnumList (el, ct, g_currentloc);
433 declareEnum (cstring ename, enumNameList el)
438 llassert (cstring_isDefined (ename));
440 cet = ctype_createEnum (ename, el);
441 e = uentry_makeEnumTagLoc (ename, cet);
442 reflectStorageClass (e);
443 e = usymtab_supGlobalEntryReturn (e);
444 cet = uentry_getType (e);
445 declareEnumList (el, cet, uentry_whereLast (e));
446 return (uentry_getAbstractType (e));
450 declareEnumList (enumNameList el, ctype c, fileloc loc)
452 bool boolnames = FALSE;
453 bool othernames = FALSE;
455 (void) context_getSaveLocation (); /* undefine it */
457 if (context_maybeSet (FLG_NUMENUMMEMBERS))
459 int maxnum = context_getValue (FLG_NUMENUMMEMBERS);
460 int num = enumNameList_size (el);
466 message ("Enumerator %s declared with %d members (limit is set to %d)",
467 ctype_unparse (c), num, maxnum),
472 enumNameList_elements (el, e)
474 uentry ue = usymtab_lookupExposeGlob (e);
475 ctype ct = uentry_getType (ue);
477 llassert (uentry_isEnumConstant (ue));
479 if (ctype_isUnknown (ct))
481 uentry_setType (ue, c);
485 if (cstring_equal (e, context_getFalseName ())
486 || cstring_equal (e, context_getTrueName ()))
492 message ("Enumerator mixes boolean name (%s) with "
495 uentry_whereLast (ue)))
502 uentry_setType (ue, ctype_bool);
503 DPRINTF (("Set type: %s / %s",
504 uentry_unparse (ue), ctype_unparse (ctype_bool)));
512 message ("Enumerator mixes boolean names (%s, %s) with "
513 "non-boolean name: %s",
514 context_getTrueName (),
515 context_getFalseName (),
517 uentry_whereLast (ue)))
526 if (!ctype_match (c, ct))
528 if (ctype_isDirectBool (ct))
530 if (cstring_equal (e, context_getFalseName ())
531 || cstring_equal (e, context_getTrueName ()))
533 DPRINTF (("Here we are!"));
539 message ("Enumerator member %s declared with "
540 "inconsistent type: %s",
541 e, ctype_unparse (c)),
542 uentry_whereLast (ue)))
544 uentry_showWhereSpecifiedExtra
545 (ue, cstring_copy (ctype_unparse (ct)));
553 message ("Enumerator member %s declared with "
554 "inconsistent type: %s",
555 e, ctype_unparse (c)),
556 uentry_whereLast (ue)))
558 uentry_showWhereSpecifiedExtra
559 (ue, cstring_copy (ctype_unparse (ct)));
564 } end_enumNameList_elements;
567 static /*@dependent@*/ uentryList currentParamList;
569 /*drl added 3-28-2001*/
570 /* this function takes a list of paramentar and generates a list
572 Currently the only constraints gnerated are MaxSet(p) >= 0 for all pointers
575 void setImplictfcnConstraints (void)
580 params = currentParamList;
582 if (constraintList_isDefined(implicitFcnConstraints) )
583 constraintList_free(implicitFcnConstraints);
585 implicitFcnConstraints = constraintList_makeNew();
587 uentryList_elements (params, el)
589 DPRINTF((message("setImplictfcnConstraints doing: %s", uentry_unparse(el) ) ));
591 s = uentry_getSref(el);
592 if (sRef_isReference (s) )
594 DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) ));
598 DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) ));
601 chagned this is MaxSet(s) == 0 to MaxSet(s) >= 0 */
603 c = constraint_makeSRefWriteSafeInt (s, 0);
604 // constraint_makeSRefSetBufferSize (s, 0);
605 implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
607 end_uentryList_elements;
611 /*@observer@*/ constraintList getImplicitFcnConstraints (void)
613 return implicitFcnConstraints;
616 void setCurrentParams (/*@dependent@*/ uentryList ue)
618 currentParamList = ue;
621 void clearCurrentParams (void)
623 currentParamList = uentryList_undefined;
627 ** requires: uentry_isFunction (e)
628 ** parameter names for current function are in currentParamList
631 static void enterFunctionParams (uentryList params)
635 uentryList_elements (params, current)
637 if (uentry_hasName (current))
639 uentry_setParamNo (current, paramno);
640 usymtab_supEntry (uentry_copy (current));
644 } end_uentryList_elements;
648 extern void enterParamsTemp (void)
650 usymtab_enterScope ();
651 enterFunctionParams (currentParamList);
654 extern void exitParamsTemp (void)
656 usymtab_quietPlainExitScope ();
659 static /*@exposed@*/ uentry clabstract_globalDeclareFunction (idDecl tid)
661 ctype deftype = idDecl_getCtype (tid);
665 DPRINTF (("Global function: %s", idDecl_unparse (tid)));
667 if (ctype_isFunction (deftype))
669 rettype = ctype_getReturnType (deftype);
673 rettype = ctype_unknown;
677 ** check has been moved here...
680 if (ctype_isFunction (idDecl_getCtype (tid)))
682 ue = uentry_makeIdFunction (tid);
683 reflectSpecialCode (ue);
684 reflectArgsUsed (ue);
688 llparseerror (message ("Inconsistent function declaration: %q",
689 idDecl_unparse (tid)));
691 tid = idDecl_replaceCtype
692 (tid, ctype_makeFunction (ctype_unknown, uentryList_undefined));
693 ue = uentry_makeIdFunction (tid);
696 reflectStorageClass (ue);
697 uentry_checkParams (ue);
698 reflectBufferConstraint (ue);
700 DPRINTF (("Supercede function: %s", uentry_unparseFull (ue)));
702 ue = usymtab_supGlobalEntryReturn (ue);
703 DPRINTF (("After supercede function: %s", uentry_unparseFull (ue)));
705 context_enterFunction (ue);
706 enterFunctionParams (uentry_getParams (ue));
708 resetStorageClass ();
709 DPRINTF (("Function: %s", uentry_unparseFull (ue)));
714 ** for now, no type checking
715 ** (must check later though!)
718 static /*@only@*/ uentry globalDeclareOldStyleFunction (idDecl tid)
723 ** check has been moved here...
726 if (cstring_equalLit (idDecl_observeId (tid), "main"))
728 context_setFlagTemp (FLG_MAINTYPE, FALSE);
731 ue = uentry_makeIdFunction (tid);
732 reflectStorageClass (ue);
733 reflectSpecialCode (ue);
734 reflectArgsUsed (ue);
735 uentry_setDefined (ue, g_currentloc);
736 uentry_checkParams (ue);
737 resetStorageClass ();
741 static void oldStyleDeclareFunction (/*@only@*/ uentry e)
743 uentryList params = saveParamList;
744 ctype rt = uentry_getType (e);
746 llassert (ctype_isFunction (rt));
748 e = usymtab_supGlobalEntryReturn (e);
750 context_enterFunction (e);
751 enterFunctionParams (params);
752 saveParamList = uentryList_undefined;
753 resetStorageClass ();
756 void clabstract_declareFunction (idDecl tid) /*@globals undef saveFunction; @*/
760 DPRINTF (("Declare function: %s", idDecl_unparse (tid)));
762 if (ProcessingParams)
764 ue = globalDeclareOldStyleFunction (tid);
769 saveFunction = uentry_undefined;
771 if (context_inRealFunction ())
773 ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
775 llparseerror (message ("Function declared inside function: %q",
776 idDecl_unparse (tid)));
778 context_quietExitFunction ();
779 ue = usymtab_supEntryReturn (ue);
783 if (context_inInnerScope ())
785 llparseerror (message ("Declaration in inner context: %q",
786 idDecl_unparse (tid)));
788 sRef_setGlobalScope ();
789 ue = uentry_makeVariableLoc (idDecl_observeId (tid),
791 ue = usymtab_supGlobalEntryReturn (ue);
792 sRef_clearGlobalScope ();
796 ue = clabstract_globalDeclareFunction (tid);
803 resetStorageClass ();
807 void declareStaticFunction (idDecl tid) /*@globals undef saveFunction; @*/
811 DPRINTF (("Declare static funciton: %s", idDecl_unparse (tid)));
813 if (ProcessingParams)
815 ue = globalDeclareOldStyleFunction (tid);
820 saveFunction = uentry_undefined;
822 if (context_inRealFunction ())
824 ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
826 llparseerror (message ("Function declared inside function: %q",
827 idDecl_unparse (tid)));
829 context_quietExitFunction ();
830 ue = usymtab_supEntryReturn (ue);
834 if (context_inInnerScope ())
836 llparseerror (message ("Declaration in inner context: %q",
837 idDecl_unparse (tid)));
839 sRef_setGlobalScope ();
840 ue = uentry_makeVariableLoc (idDecl_observeId (tid),
842 ue = usymtab_supGlobalEntryReturn (ue);
843 sRef_clearGlobalScope ();
847 ctype deftype = idDecl_getCtype (tid);
850 if (ctype_isFunction (deftype))
852 rettype = ctype_getReturnType (deftype);
856 rettype = ctype_unknown;
860 ** check has been moved here...
863 if (ctype_isFunction (idDecl_getCtype (tid)))
865 ue = uentry_makeIdFunction (tid);
866 reflectSpecialCode (ue);
867 reflectArgsUsed (ue);
871 llparseerror (message ("Inconsistent function declaration: %q",
872 idDecl_unparse (tid)));
874 tid = idDecl_replaceCtype
875 (tid, ctype_makeFunction (ctype_unknown, uentryList_undefined));
876 ue = uentry_makeIdFunction (tid);
879 reflectStorageClass (ue);
880 uentry_setStatic (ue);
882 uentry_checkParams (ue);
883 reflectBufferConstraint (ue);
885 DPRINTF (("Sub global entry: %s", uentry_unparse (ue)));
886 ue = usymtab_supGlobalEntryReturn (ue);
888 context_enterFunction (ue);
889 enterFunctionParams (uentry_getParams (ue));
890 resetStorageClass ();
897 resetStorageClass ();
902 checkTypeDecl (uentry e, ctype rep)
904 cstring n = uentry_getName (e);
906 DPRINTF (("Check type decl: %s", uentry_unparseFull (e)));
908 if (cstring_equal (context_getBoolName (), n))
910 ctype rrep = ctype_realType (rep);
913 ** for abstract enum types, we need to fix the enum members:
914 ** they should have the abstract type, not the rep type.
917 if (ctype_isEnum (ctype_realType (rrep)))
919 enumNameList el = ctype_elist (rrep);
921 enumNameList_elements (el, ye)
923 if (usymtab_existsGlob (ye))
925 uentry ue = usymtab_lookupSafe (ye);
926 uentry_setType (ue, ctype_bool);
929 if (cstring_equal (context_getTrueName (), ye)
930 || cstring_equal (context_getFalseName (), ye))
938 message ("Member of boolean enumerated type definition "
939 "does not match name set to represent TRUE "
942 message ("Use -boolfalse and -booltrue to set the "
943 "name of false and true boolean values."),
944 uentry_whereDefined (e));
946 } end_enumNameList_elements;
950 if (usymtab_exists (n))
952 usymId llm = usymtab_getId (n);
953 uentry le = usymtab_getTypeEntry (llm);
955 uentry_setDeclared (e, g_currentloc);
956 uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le)));
958 DPRINTF (("Here we are: %s / %s",
959 n, context_getBoolName ()));
961 if (uentry_isAbstractDatatype (le))
963 ctype rrep = ctype_realType (rep);
965 DPRINTF (("Abstract type: %s", uentry_unparseFull (le)));
968 ** for abstract enum types, we need to fix the enum members:
969 ** they should have the abstract type, not the rep type.
972 if (ctype_isEnum (ctype_realType (rrep)))
974 ctype at = uentry_getAbstractType (le);
975 enumNameList el = ctype_elist (rrep);
977 enumNameList_elements (el, ye)
979 if (usymtab_existsGlob (ye))
981 uentry ue = usymtab_lookupSafe (ye);
983 llassert (uentry_isEitherConstant (ue));
984 llassertprint (ctype_match (uentry_getType (ue), rrep),
985 ("Bad enum: %s / %s",
987 ctype_unparse (rrep)));
989 uentry_setType (ue, at);
991 } end_enumNameList_elements;
994 if (uentry_isMutableDatatype (le))
996 /* maybe more complicated if abstract and immutable ? */
998 if (!ctype_isRealPointer (rep) && !ctype_isRealAbstract (rep))
1002 message ("Mutable abstract type %s declared without pointer "
1003 "indirection: %s (violates assignment semantics)",
1004 n, ctype_unparse (rep)),
1005 uentry_whereDefined (e));
1007 uentry_setMutable (e);
1014 fileloc fl = uentry_whereDeclared (e);
1016 if (context_getFlag (FLG_LIKELYBOOL)
1017 && !context_getFlag (FLG_BOOLINT))
1019 if ((cstring_equalLit (n, "BOOL")
1020 || cstring_equalLit (n, "Bool")
1021 || cstring_equalLit (n, "bool")
1022 || cstring_equalLit (n, "boolean")
1023 || cstring_equalLit (n, "Boolean")
1024 || cstring_equalLit (n, "BOOLEAN"))
1025 && !(cstring_equal (n, context_getBoolName ())))
1027 if (context_setBoolName ()) {
1030 message ("Type %s is probably meant as a boolean type, but does "
1031 "not match the boolean type name \"%s\".",
1033 context_getBoolName ()),
1038 message ("Type %s is probably meant as a boolean type, "
1039 "but the boolean type name is not set. "
1040 "Use -booltype %s to set it.",
1047 if (!uentry_isStatic (e)
1048 && !ctype_isFunction (uentry_getType (e))
1049 && !fileloc_isLib (fl)
1050 && !fileloc_isImport (fl)
1051 && fileloc_isHeader (fl))
1053 voptgenerror (FLG_EXPORTTYPE,
1054 message ("Type exported, but not specified: %s\n", n),
1063 fixUentryList (idDeclList tl, qtype q)
1065 uentryList f = uentryList_new ();
1067 idDeclList_elements (tl, i)
1069 if (idDecl_isDefined (i))
1075 (void) idDecl_fixBase (i, q);
1078 ** implicit annotations
1081 (void) fixStructDecl (i);
1083 ue = uentry_makeIdVariable (i);
1084 rt = ctype_realType (uentry_getType (ue));
1087 ** where is this here???
1089 if (ctype_isArray (rt) || ctype_isSU (rt))
1091 sRef_setAllocated (uentry_getSref (ue), uentry_whereDefined (ue));
1097 if (uentry_isValid (old = uentryList_lookupField (f, uentry_rawName (ue))))
1099 if (optgenerror (FLG_SYNTAX,
1100 message ("Field name reused: %s", uentry_rawName (ue)),
1101 uentry_whereDefined (ue)))
1103 llgenmsg (message ("Previous use of %s", uentry_rawName (ue)),
1104 uentry_whereDefined (old));
1108 f = uentryList_add (f, ue);
1110 } end_idDeclList_elements;
1112 idDeclList_free (tl);
1117 ** This is a hack to support unnamed struct/union fields as done by
1118 ** Microsoft VC++. It is not supported by the ANSI standard.
1120 ** The inner fields are added to the outer structure. This is meaningful
1121 ** for nesting structs inside unions, but lclint does no related
1126 fixUnnamedDecl (qtype q)
1128 ctype ct = ctype_realType (qtype_getType (q));
1130 if (ctype_isStruct (ct) || ctype_isUnion (ct))
1132 uentryList res = ctype_getFields (ct);
1134 return (uentryList_copy (res));
1141 return uentryList_undefined;
1144 void setStorageClass (storageClassCode sc)
1150 setProcessingIterVars (uentry iter)
1152 ProcessingIterVars = TRUE;
1154 saveIterParamNo = 0;
1158 setProcessingGlobalsList ()
1160 ProcessingGlobals = TRUE;
1161 fcnNoGlobals = FALSE;
1164 static bool ProcessingGlobMods = FALSE;
1167 setProcessingGlobMods ()
1169 ProcessingGlobMods = TRUE;
1173 clearProcessingGlobMods ()
1175 ProcessingGlobMods = FALSE;
1179 isProcessingGlobMods ()
1181 return (ProcessingGlobMods);
1184 static void resetGlobals (void)
1186 ProcessingGlobals = FALSE;
1187 fcnNoGlobals = FALSE;
1191 unsetProcessingGlobals ()
1193 ProcessingGlobals = FALSE;
1197 setProcessingVars (/*@only@*/ qtype q)
1199 ProcessingVars = TRUE;
1200 qtype_free (processingType);
1205 setGenericParamList (/*@dependent@*/ uentryList pm)
1207 ProcessingParams = TRUE;
1212 setProcessingTypedef (/*@only@*/ qtype q)
1214 ProcessingTypedef = TRUE;
1216 qtype_free (processingType);
1221 unsetProcessingVars ()
1223 resetStorageClass ();
1224 ProcessingVars = FALSE;
1230 if (ProcessingParams)
1232 if (uentry_isInvalid (saveFunction))
1234 llbuglit ("unsetProcessingVars: no saved function\n");
1238 ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
1239 uentryList params = uentryList_copy (saveParamList);
1240 ctype ct2 = ctype_makeFunction (ct, params);
1242 uentry_setType (saveFunction, ct2);
1243 ProcessingParams = FALSE;
1245 reflectBufferConstraint (saveFunction);
1246 oldStyleDeclareFunction (saveFunction);
1247 saveFunction = uentry_undefined;
1254 ** If the paramlist used a type name, we could be here.
1257 llfatalerror (message ("%q: Old-style function parameter list uses a "
1258 "type name.", fileloc_unparse (g_currentloc)));
1265 if (uentry_isValid (saveFunction))
1268 ** old style declaration
1271 ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
1274 uentryList_elements (saveParamList, current)
1276 uentry_setType (current, ctype_int); /* all params are ints */
1277 } end_uentryList_elements;
1279 ct2 = ctype_makeParamsFunction (ct, uentryList_copy (saveParamList));
1281 uentry_setType (saveFunction, ct2);
1282 ProcessingParams = FALSE;
1284 oldStyleDeclareFunction (saveFunction);
1285 saveFunction = uentry_undefined;
1290 unsetProcessingTypedef ()
1292 ProcessingTypedef = FALSE;
1295 void checkConstant (qtype t, idDecl id)
1299 id = idDecl_fixBase (id, t);
1300 e = uentry_makeIdConstant (id);
1302 reflectStorageClass (e);
1303 resetStorageClass ();
1305 usymtab_supGlobalEntry (e);
1308 void checkValueConstant (qtype t, idDecl id, exprNode e)
1312 id = idDecl_fixBase (id, t);
1313 ue = uentry_makeIdConstant (id);
1314 reflectStorageClass (ue);
1315 resetStorageClass ();
1317 if (exprNode_isDefined (e))
1319 if (!exprNode_matchType (uentry_getType (ue), e))
1322 (exprNode_getType (e), e,
1323 uentry_getType (ue), exprNode_undefined,
1324 message ("Constant %q initialized to type %t, expects %t: %s",
1325 uentry_getName (ue),
1326 exprNode_getType (e),
1327 uentry_getType (ue),
1328 exprNode_unparse (e)),
1333 if (exprNode_hasValue (e))
1335 uentry_mergeConstantValue (ue, multiVal_copy (exprNode_getValue (e)));
1340 usymtab_supGlobalEntry (ue);
1343 void processNamedDecl (idDecl t)
1345 if (qtype_isUndefined (processingType))
1347 llparseerror (message ("No type before declaration name: %q", idDecl_unparse (t)));
1349 processingType = qtype_create (ctype_unknown);
1352 t = idDecl_fixBase (t, processingType);
1354 DPRINTF (("Declare: %s", idDecl_unparse (t)));
1356 if (ProcessingGlobals)
1358 cstring id = idDecl_getName (t);
1359 uentry ue = usymtab_lookupSafe (id);
1361 if (!uentry_isValid (ue))
1363 llerror (FLG_UNRECOG,
1364 message ("Variable used in globals list is undeclared: %s", id));
1368 if (!ctype_match (uentry_getType (ue), idDecl_getCtype (t)))
1372 message ("Variable %s used in globals list declared %s, "
1374 id, ctype_unparse (uentry_getType (ue)),
1375 ctype_unparse (idDecl_getCtype (t))),
1380 sRef sr = sRef_copy (uentry_getSref (ue));
1381 reflectGlobalQualifiers (sr, idDecl_getQuals (t));
1385 else if (ProcessingVars)
1390 ct = ctype_realType (idDecl_getCtype (t));
1392 if (ProcessingParams)
1394 cstring id = idDecl_getName (t);
1395 int paramno = uentryList_lookupRealName (saveParamList, id);
1399 uentry cparam = uentryList_getN (saveParamList, paramno);
1401 uentry_setType (cparam, idDecl_getCtype (t));
1402 uentry_reflectQualifiers (cparam, idDecl_getQuals (t));
1403 uentry_setDeclaredOnly (cparam, context_getSaveLocation ());
1408 (message ("Old style declaration uses unlisted parameter: %s",
1416 if (context_inIterDef ())
1418 cstring pname = makeParam (idDecl_observeId (t));
1419 uentry p = usymtab_lookupSafe (pname);
1421 cstring_free (pname);
1423 if (uentry_isYield (p))
1425 e = uentry_makeParam (t, sRef_getParam (uentry_getSref (p)));
1426 uentry_checkYieldParam (p, e);
1427 usymtab_supEntrySref (e);
1432 if ((hasSpecialCode () || argsUsed)
1433 && ctype_isFunction (idDecl_getCtype (t)))
1435 e = uentry_makeIdFunction (t);
1436 reflectSpecialCode (e);
1437 reflectArgsUsed (e);
1441 e = uentry_makeIdVariable (t);
1444 loc = uentry_whereDeclared (e);
1447 if (context_inGlobalScope ())
1449 uentry_checkParams was here!
1453 if (ctype_isFunction (uentry_getType (e)))
1455 clabstract_prepareFunction (e);
1456 reflectBufferConstraint (e);
1459 DPRINTF (("Superceding... %s", uentry_unparseFull (e)));
1460 e = usymtab_supEntrySrefReturn (e);
1461 DPRINTF (("After superceding... %s", uentry_unparseFull (e)));
1463 if (uentry_isExtern (e) && !context_inGlobalScope ())
1467 message ("Declaration using extern inside function scope: %q",
1468 uentry_unparse (e)),
1471 uentry_setDefined (e, fileloc_getExternal ());
1472 sRef_setDefined (uentry_getSref (e), fileloc_getExternal ());
1475 if (uentry_isFunction (e))
1477 if (!context_inXHFile ())
1479 checkParamNames (e);
1483 if (uentry_isVar (e) && uentry_isCheckedUnknown (e))
1485 sRef sr = uentry_getSref (e);
1487 if (sRef_isLocalVar (sr))
1489 if (context_getFlag (FLG_IMPCHECKMODINTERNALS))
1491 uentry_setCheckMod (e);
1495 uentry_setUnchecked (e);
1498 else if (sRef_isFileStatic (sr))
1500 if (context_getFlag (FLG_IMPCHECKEDSTRICTSTATICS))
1502 uentry_setCheckedStrict (e);
1504 else if (context_getFlag (FLG_IMPCHECKEDSTATICS))
1506 uentry_setChecked (e);
1508 else if (context_getFlag (FLG_IMPCHECKMODSTATICS))
1510 uentry_setCheckMod (e);
1517 else /* real global */
1519 llassert (sRef_isRealGlobal (sr));
1521 if (context_getFlag (FLG_IMPCHECKEDSTRICTGLOBALS))
1523 uentry_setCheckedStrict (e);
1525 else if (context_getFlag (FLG_IMPCHECKEDGLOBALS))
1527 uentry_setChecked (e);
1529 else if (context_getFlag (FLG_IMPCHECKMODGLOBALS))
1531 uentry_setCheckMod (e);
1541 else if (ProcessingTypedef)
1543 ctype ct = idDecl_getCtype (t);
1546 DPRINTF (("Processing typedef: %s", ctype_unparse (ct)));
1548 e = uentry_makeIdDatatype (t);
1550 if (cstring_equal (idDecl_getName (t), context_getBoolName ())) {
1551 ctype rt = ctype_realType (ct);
1553 if (ctype_isEnum (rt)) {
1556 if (!(ctype_isInt (rt)
1557 || ctype_isUnknown (rt)
1558 || ctype_isChar (rt))) {
1561 message ("Boolean type %s defined using non-standard type %s (integral, char or enum type expected)",
1562 context_getBoolName (),
1563 ctype_unparse (ct)),
1564 uentry_whereLast (e));
1568 uentry_setType (e, ct);
1572 reflectStorageClass (e);
1573 checkTypeDecl (e, ct);
1575 e = usymtab_supReturnTypeEntry (e);
1579 llparseerror (message ("Suspect missing struct or union keyword: %q",
1580 idDecl_unparse (t)));
1586 ** moved from grammar
1589 static idDecl fixStructDecl (/*@returned@*/ idDecl d)
1591 if (ctype_isVisiblySharable (idDecl_getCtype (d))
1592 && context_getFlag (FLG_STRUCTIMPONLY))
1594 if (!qualList_hasAliasQualifier (idDecl_getQuals (d)))
1596 if (qualList_hasExposureQualifier (idDecl_getQuals (d)))
1598 idDecl_addQual (d, qual_createDependent ());
1602 idDecl_addQual (d, qual_createImpOnly ());
1611 declareUnnamedStruct (/*@only@*/ uentryList f)
1613 DPRINTF (("Unnamed struct: %s", uentryList_unparse (f)));
1615 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1617 int num = uentryList_size (f);
1618 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1623 (FLG_NUMSTRUCTFIELDS,
1624 message ("Structure declared with %d fields "
1625 "(limit is set to %d)",
1631 return (ctype_createUnnamedStruct (f));
1635 declareUnnamedUnion (/*@only@*/ uentryList f)
1637 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1639 int num = uentryList_size (f);
1640 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1645 (FLG_NUMSTRUCTFIELDS,
1646 message ("Union declared with %d fields "
1647 "(limit is set to %d)",
1653 return (ctype_createUnnamedUnion (f));
1656 ctype declareStruct (cstring id, /*@only@*/ uentryList f)
1660 int num = uentryList_size (f);
1662 DPRINTF (("Declare struct: %s / %s", id, uentryList_unparse (f)));
1664 ct = ctype_createStruct (cstring_copy (id), f);
1666 DPRINTF (("Ctype: %s", ctype_unparse (ct)));
1668 ue = uentry_makeStructTagLoc (id, ct);
1670 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
1672 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1674 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1679 (FLG_NUMSTRUCTFIELDS,
1680 message ("Structure %q declared with %d fields "
1681 "(limit is set to %d)",
1682 uentry_getName (ue), num, max),
1683 uentry_whereLast (ue));
1687 return (usymtab_supTypeEntry (ue));
1690 ctype declareUnion (cstring id, uentryList f)
1694 int num = uentryList_size (f);
1696 ct = ctype_createUnion (cstring_copy (id), f);
1697 ue = uentry_makeUnionTagLoc (id, ct);
1699 if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1701 int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1706 (FLG_NUMSTRUCTFIELDS,
1707 message ("Union %q declared with %d fields "
1708 "(limit is set to %d)",
1709 uentry_getName (ue), num, max),
1710 uentry_whereLast (ue));
1714 return (usymtab_supTypeEntry (ue));
1717 ctype handleStruct (/*@only@*/ cstring id)
1719 if (usymtab_existsStructTag (id))
1721 ctype ct = uentry_getAbstractType (usymtab_lookupStructTag (id));
1728 return (ctype_createForwardStruct (id));
1732 ctype handleUnion (/*@only@*/ cstring id)
1734 if (usymtab_existsUnionTag (id))
1736 ctype ret = uentry_getAbstractType (usymtab_lookupUnionTag (id));
1742 return (ctype_createForwardUnion (id));
1747 handleEnum (cstring id)
1749 if (usymtab_existsEnumTag (id))
1751 ctype ret = uentry_getAbstractType (usymtab_lookupEnumTag (id));
1757 return (declareEnum (id, enumNameList_new ()));
1761 bool processingIterVars (void)
1763 return ProcessingIterVars;
1766 uentry getCurrentIter (void)
1771 static bool flipOldStyle = FALSE;
1772 static bool flipNewStyle = TRUE;
1774 void setFlipOldStyle () { flipOldStyle = TRUE; }
1775 bool isFlipOldStyle () { return flipOldStyle; }
1776 bool isNewStyle () { return flipNewStyle; }
1777 void setNewStyle () { flipNewStyle = TRUE; }
1779 /*@dependent@*/ uentryList handleParamIdList (/*@dependent@*/ uentryList params)
1784 ** this is a really YUCKY hack to handle old style
1788 voptgenerror (FLG_OLDSTYLE,
1789 cstring_makeLiteral ("Old style function declaration"),
1792 uentryList_elements (params, current)
1794 uentry_setParam (current);
1795 uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown));
1797 } end_uentryList_elements;
1799 setGenericParamList (params);
1800 g_expectingTypeName = TRUE;
1805 /*@dependent@*/ uentryList handleParamTypeList (/*@returned@*/ uentryList params)
1809 uentryList_fixMissingNames (params);
1811 voptgenerror (FLG_OLDSTYLE,
1812 cstring_makeLiteral ("Old style function declaration."),
1815 setGenericParamList (params);
1816 flipOldStyle = FALSE;
1817 g_expectingTypeName = TRUE;
1826 ctype c = ctype_unknown;
1827 cstring id = cstring_makeLiteral ("va_alist");
1830 if (ProcessingParams)
1832 int i = uentryList_lookupRealName (saveParamList, id);
1836 e = uentry_makeVariableSrefParam (id, c, sRef_makeParam (i, c));
1840 e = uentry_undefined; /* suppress gcc message */
1841 llfatalerrorLoc (cstring_makeLiteral ("va_dcl used without va_alist"));
1846 llerror (FLG_SYNTAX, cstring_makeLiteral ("va_dcl used outside of function declaration"));
1847 e = uentry_makeVariableLoc (id, c);
1851 uentry_setUsed (e, g_currentloc);
1852 usymtab_supEntrySref (e);
1855 /*@exposed@*/ sRef modListPointer (/*@exposed@*/ sRef s)
1857 ctype ct = sRef_getType (s);
1858 ctype rt = ctype_realType (ct);
1860 if (ctype_isAP (rt))
1862 if (context_inHeader () && ctype_isAbstract (ct))
1867 ("Modifies clause in header file dereferences abstract "
1868 "type %s (interface modifies clause should not depend "
1869 "on or expose type representation): %q",
1875 return (sRef_constructPointer (s));
1879 if (ctype_isKnown (rt))
1883 message ("Implementation modifies clause dereferences non-pointer (type %s): %q",
1893 /*@exposed@*/ sRef modListFieldAccess (sRef s, cstring f)
1895 ctype ct = sRef_getType (s);
1896 ctype rt = ctype_realType (ct);
1898 if (ctype_isStructorUnion (rt))
1900 uentry tf = uentryList_lookupField (ctype_getFields (rt), f);
1902 if (uentry_isUndefined (tf))
1904 voptgenerror (FLG_TYPE,
1905 message ("Modifies list accesses non-existent "
1906 "field %s of %t: %q", f, ct,
1911 return sRef_undefined;
1915 if (ctype_isAbstract (ct) && context_inHeader ())
1920 ("Modifies clause in header file accesses abstract "
1921 "type %s (interface modifies clause should not depend "
1922 "on or expose type representation): %q",
1929 cstring_markOwned (f);
1930 return (sRef_makeField (s, f));
1936 message ("Modifies clause dereferences non-pointer (type %s): %q",
1946 /*@dependent@*/ sRef clabstract_unrecognizedGlobal (cstring s)
1948 if (cstring_equalLit (s, "nothing"))
1950 return sRef_makeNothing ();
1952 else if (cstring_equalLit (s, "internalState"))
1954 return sRef_makeInternalState ();
1956 else if (cstring_equalLit (s, "fileSystem")
1957 || cstring_equalLit (s, "systemState"))
1959 return sRef_makeSystemState ();
1965 message ("Unrecognized identifier in globals list: %s", s),
1968 return sRef_undefined;
1972 /*@exposed@*/ sRef modListArrowAccess (sRef s, cstring f)
1974 ctype ct = sRef_getType (s);
1975 ctype rt = ctype_realType (ct);
1977 if (ctype_isRealPointer (rt))
1979 ctype b = ctype_baseArrayPtr (rt);
1980 ctype rb = ctype_realType (b);
1982 if (ctype_isStructorUnion (rb))
1984 uentry tf = uentryList_lookupField (ctype_getFields (rb), f);
1986 if (uentry_isUndefined (tf))
1988 voptgenerror (FLG_TYPE,
1989 message ("Modifies list arrow accesses non-existent "
1990 "field %s of %t: %q", f, b,
1995 return sRef_undefined;
1999 if (context_inHeader ())
2001 if (ctype_isAbstract (b))
2006 ("Modifies clause in header file arrow accesses abstract "
2007 "type %s (interface modifies clause should not depend "
2008 "on or expose type representation): %q",
2016 if (ctype_isAbstract (ct))
2021 ("Modifies clause in header file arrow accesses abstract "
2022 "type %s (interface modifies clause should not depend "
2023 "on or expose type representation): %q",
2031 cstring_markOwned (f);
2032 return (sRef_makeArrow (s, f));
2038 message ("Modifies clause arrow accesses pointer to "
2039 "non-structure (type %s): %q",
2049 message ("Modifies clause arrow accesses non-pointer (type %s): %q",
2059 sRef checkStateClausesId (uentry ue)
2061 cstring s = uentry_rawName (ue);
2063 if (sRef_isFileOrGlobalScope (uentry_getSref (ue)))
2067 message ("Global variable %s used special clause. (Global variables "
2068 "are not recognized in special clauses. If there is "
2069 "sufficient interest in support for this, it may be "
2070 "added to a future release. Send mail to "
2071 "lclint@cs.virginia.edu.)",
2075 return sRef_undefined;
2079 if (cstring_equalLit (s, "result"))
2083 message ("Special clause list uses %s which is a variable and has special "
2084 "meaning in a modifies list. (Special meaning assumed.)", s),
2087 uentry_showWhereDeclared (ue);
2091 return uentry_getSref (ue);
2097 don;t know what the real date is...
2103 based on checkSpecClausesId
2106 sRef checkbufferConstraintClausesId (uentry ue)
2108 cstring s = uentry_rawName (ue);
2109 if (cstring_equalLit (s, "result"))
2113 message ("Special clause list uses %s which is a variable and has special "
2114 "meaning in a modifies list. (Special meaning assumed.)", s),
2117 uentry_showWhereDeclared (ue);
2121 return sRef_saveCopy( uentry_getSref (ue) );
2124 void checkModifiesId (uentry ue)
2126 cstring s = uentry_rawName (ue);
2128 if (cstring_equalLit (s, "nothing")
2129 || cstring_equalLit (s, "internalState")
2130 || cstring_equalLit (s, "systemState")
2131 || (cstring_equalLit (s, "fileSystem")))
2135 message ("Modifies list uses %s which is a variable and has special "
2136 "meaning in a modifies list. (Special meaning assumed.)", s),
2139 uentry_showWhereDeclared (ue);
2144 /*@exposed@*/ sRef fixModifiesId (cstring s)
2147 cstring pname = makeParam (s);
2148 uentry ue = usymtab_lookupSafe (pname);
2150 cstring_free (pname);
2152 if (cstring_equalLit (s, "nothing"))
2154 ret = sRef_makeNothing ();
2156 else if (cstring_equalLit (s, "internalState"))
2158 ret = sRef_makeInternalState ();
2160 else if (cstring_equalLit (s, "fileSystem")
2161 || cstring_equalLit (s, "systemState"))
2163 ret = sRef_makeSystemState ();
2167 ret = sRef_undefined;
2170 if (sRef_isValid (ret))
2172 if (uentry_isValid (ue))
2176 message ("Modifies list uses %s which is a parameter and has special "
2177 "meaning in a modifies list. (Special meaning assumed.)", s),
2183 if (uentry_isValid (ue))
2185 ret = uentry_getSref (ue);
2189 fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s));
2190 ret = sRef_undefined;
2194 message ("Unrecognized identifier in modifies comment: %s", s),
2204 sRef fixStateClausesId (cstring s)
2207 cstring pname = makeParam (s);
2208 uentry ue = usymtab_lookupSafe (pname);
2210 cstring_free (pname);
2212 if (cstring_equalLit (s, "result"))
2214 ret = sRef_makeResult ();
2218 ret = sRef_undefined;
2221 if (sRef_isValid (ret))
2223 if (uentry_isValid (ue))
2227 message ("Special clause uses %s which is a parameter and has special "
2228 "meaning in a special clause. (Special meaning assumed.)", s),
2234 if (uentry_isValid (ue))
2236 ret = uentry_getSref (ue);
2238 if (sRef_isFileOrGlobalScope (ret))
2242 message ("Global variable %s used special clause. (Global variables "
2243 "are not recognized in special clauses. If there is "
2244 "sufficient interest in support for this, it may be "
2245 "added to a future release. Send mail to "
2246 "lclint@cs.virginia.edu.)",
2250 ret = sRef_undefined;
2255 fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s));
2256 ret = sRef_undefined;
2260 message ("Unrecognized identifier in special clause: %s", s),
2270 sRef modListArrayFetch (/*@exposed@*/ sRef s, /*@unused@*/ sRef mexp)
2272 ctype ct = sRef_getType (s);
2273 ctype rt = ctype_realType (ct);
2275 if (ctype_isAP (rt))
2277 if (context_inHeader () && ctype_isAbstract (ct))
2282 ("Modifies clause in header file indexes abstract "
2283 "type %s (interface modifies clause should not depend "
2284 "on or expose type representation): %q",
2290 return (sRef_makeAnyArrayFetch (s));
2297 ("Implementation modifies clause uses array fetch on non-array (type %s): %q",
2298 ctype_unparse (ct), sRef_unparse (s)),
2304 static void clabstract_prepareFunction (uentry e)
2306 uentry_checkParams (e);
2307 DPRINTF (("After prepare: %s", uentry_unparseFull (e)));
2310 sRef clabstract_checkGlobal (exprNode e)
2313 llassert (exprNode_isInitializer (e));
2315 s = exprNode_getSref (e);
2316 DPRINTF (("Initializer: %s -> %s", exprNode_unparse (e), sRef_unparse (s)));
2319 return sRef_copy (s);