]> andersk Git - splint.git/blob - src/clabstract.c
Fixes after removing -unrecogcomments flag for make splintme.
[splint.git] / src / clabstract.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
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.
10 ** 
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.
15 ** 
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.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** clabstract.c
26 **
27 ** ASTs for C grammar
28 **
29 */
30
31 # include "splintMacros.nf"
32 # include "basic.h"
33 # include "cgrammar.h"
34 # include "usymtab_interface.h"
35
36 # include "structNames.h"
37 # include "nameChecks.h"
38
39 # include "cscannerHelp.h"
40
41 # ifdef SANITIZER
42 # include "sgrammar_tokens.h"
43 # else
44 # include "cgrammar_tokens.h"
45 # endif
46
47 /*
48 ** Lots of variables are needed because of interactions with the
49 ** parser.  This is easier than restructuring the grammar so the
50 ** right values are available in the right place.
51 */
52
53 /*drl*/
54 static /*@only@*/ constraintList implicitFcnConstraints = NULL;
55
56 static void clabstract_prepareFunction (uentry p_e) /*@modifies p_e@*/ ;
57 static bool fcnNoGlobals = FALSE;
58 static void processVariable (/*@temp@*/ idDecl p_t) /*@modifies internalState@*/ ;
59
60 static bool s_processingVars = FALSE;
61 static bool s_processingParams = FALSE;
62 static bool s_processingGlobals = FALSE;
63 static bool s_processingTypedef = FALSE;
64 static bool s_processingIterVars = FALSE;
65 static /*@only@*/ qtype processingType = qtype_undefined;
66 static uentry currentIter = uentry_undefined;
67 static /*@dependent@*/ uentryList saveParamList;  /* for old style functions */
68 static /*@owned@*/ uentry saveFunction = uentry_undefined;
69 static int saveIterParamNo;
70 static idDecl fixStructDecl (/*@returned@*/ idDecl p_d);
71 static void checkTypeDecl (uentry p_e, ctype p_rep);
72 static /*@dependent@*/ fileloc saveStoreLoc = fileloc_undefined;
73 static storageClassCode storageClass = SCNONE;
74 static void declareEnumList (/*@temp@*/ enumNameList p_el, ctype p_c, fileloc p_loc);
75 static void resetGlobals (void);
76 static /*@null@*/ qual specialFunctionCode;
77 static bool argsUsed = FALSE;
78
79 extern void clabstract_initMod () 
80 {
81   specialFunctionCode = qual_createUnknown ();
82   DPRINTF (("Initialized: %s", qual_unparse (specialFunctionCode)));
83 }
84
85 static bool hasSpecialCode (void)
86 {
87   return (!qual_isUnknown (specialFunctionCode));
88 }
89
90 extern void setArgsUsed (void)
91 {
92   if (argsUsed)
93     {
94       voptgenerror
95         (FLG_SYNTAX,
96          cstring_makeLiteral ("Multiple ARGSUSED comments for one function"),
97          g_currentloc);
98     }
99
100   argsUsed = TRUE;
101 }
102
103 static void reflectArgsUsed (uentry ue)
104 {
105   if (argsUsed)
106     {
107       if (uentry_isFunction (ue))
108         {
109           uentryList params = uentry_getParams (ue);
110
111           uentryList_elements (params, el)
112             {
113               uentry_setUsed (el, fileloc_undefined);
114             } end_uentryList_elements ;
115         }
116
117       argsUsed = FALSE;
118     }
119 }
120               
121 extern void setSpecialFunction (qual qu)
122 {
123   if (!qual_isUnknown (specialFunctionCode))
124     {
125       voptgenerror (FLG_SYNTAX,
126                     message ("Multiple special function codes: %s, %s "
127                              "(first code is ignored)",
128                              qual_unparse (specialFunctionCode),
129                              qual_unparse (qu)),
130                     g_currentloc);
131     }
132
133   specialFunctionCode = qu;
134 }
135
136 static void reflectSpecialCode (uentry ue)
137 {
138   if (qual_isUnknown (specialFunctionCode)) {
139     ;
140   } else if (qual_isPrintfLike (specialFunctionCode)) {
141     uentry_setPrintfLike (ue);
142   } else if (qual_isScanfLike (specialFunctionCode)) {
143     uentry_setScanfLike (ue);
144   } else if (qual_isMessageLike (specialFunctionCode)) {
145     uentry_setMessageLike (ue);
146   } else {
147     BADBRANCH;
148   }
149
150   specialFunctionCode = qual_createUnknown ();
151 }
152
153 static void resetStorageClass (void)
154 {
155   qtype_free (processingType);
156   processingType = qtype_undefined;
157   storageClass = SCNONE;
158 }
159
160 static void reflectStorageClass (uentry u)
161 {
162   if (storageClass == SCSTATIC)
163     {
164       uentry_setStatic (u);
165     }
166   else if (storageClass == SCEXTERN)
167     {
168       uentry_setExtern (u);
169     }
170   else
171     {
172       ; /* no storage class */
173     }
174
175   }
176
177 void storeLoc ()
178 {
179   saveStoreLoc = g_currentloc;
180 }
181
182 void setFunctionNoGlobals (void)
183 {
184   fcnNoGlobals = TRUE;
185 }
186
187 static void reflectGlobalQualifiers (sRef sr, qualList quals)
188 {
189   DPRINTF (("Reflect global qualifiers: %s / %s", 
190             sRef_unparseFull (sr), qualList_unparse (quals)));
191
192   qualList_elements (quals, qel)
193     {
194       if (qual_isGlobalQual (qel)) /* undef, killed */
195         {
196           sstate oldstate = sRef_getDefState (sr);
197           sstate defstate = sstate_fromQual (qel);
198           
199           if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
200               || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
201             {
202               defstate = SS_UNDEFKILLED;
203             }
204           else 
205             {
206               ; /* any errors? */
207             }
208           
209           sRef_setDefState (sr, defstate, fileloc_undefined);
210           DPRINTF (("State: %s", sRef_unparseFull (sr)));
211         }
212       else if (qual_isAllocQual (qel)) /* out, partial, reldef, etc. */
213         {
214           ctype realType = sRef_getType (sr);
215           sstate defstate = sstate_fromQual (qel);
216           
217           if (qual_isRelDef (qel))
218             {
219               ; /* okay anywhere */
220             }
221           else
222             {
223               if (!ctype_isAP (realType) 
224                   && !ctype_isSU (realType)
225                   && !ctype_isUnknown (realType)
226                   && !ctype_isAbstract (sRef_getType (sr)))
227                 {
228                   llerror 
229                     (FLG_SYNTAX, 
230                      message ("Qualifier %s used on non-pointer or struct: %q",
231                               qual_unparse (qel), sRef_unparse (sr)));
232                   
233                 }
234             }
235           
236           sRef_setDefState (sr, defstate, fileloc_undefined);
237         }
238       else if (qual_isNull (qel))
239         {
240           sRef_setNullState (sr, NS_POSNULL, fileloc_undefined);
241         }
242       else if (qual_isRelNull (qel))
243         {
244           sRef_setNullState (sr, NS_RELNULL, fileloc_undefined);
245         }
246       else if (qual_isNotNull (qel))
247         {
248           sRef_setNullState (sr, NS_MNOTNULL, fileloc_undefined);
249         }
250       else
251         {
252           if (qual_isCQual (qel))
253             {
254               ; /* okay */
255             }
256           else
257             {
258               llerror (FLG_SYNTAX,
259                        message ("Qualifier %s cannot be used in a globals list",
260                                 qual_unparse (qel)));
261             }
262         }
263     } end_qualList_elements;
264 }
265
266 sRef clabstract_createGlobal (sRef sr, qualList quals)
267 {
268   sRef res;
269
270   if (sRef_isValid (sr))
271     {
272       res = sRef_copy (sr);
273       DPRINTF (("Reflecting quals: %s / %s", sRef_unparse (sr), qualList_unparse (quals)));
274       reflectGlobalQualifiers (res, quals);
275       DPRINTF (("==> %s", sRef_unparseFull (res)));
276     }
277   else
278     {
279       res = sRef_undefined;
280     }
281
282   qualList_free (quals);
283   return res;
284 }
285
286 extern void declareCIter (cstring name, /*@owned@*/ uentryList params)
287 {
288   uentry ue;
289
290   ue = uentry_makeIter (name, 
291                         ctype_makeFunction (ctype_void, params), 
292                         fileloc_copy (g_currentloc));
293
294   usymtab_supEntry (uentry_makeEndIter (name, fileloc_copy (g_currentloc)));
295   ue = usymtab_supGlobalEntryReturn (ue);
296 }
297
298 extern void nextIterParam (void)
299 {
300   llassert (s_processingIterVars);
301   saveIterParamNo++;
302 }
303
304 extern int iterParamNo (void)
305 {
306   llassert (s_processingIterVars);
307   return saveIterParamNo;
308 }
309
310 /*
311 ** yucky hacks to put it in the right place
312 */
313
314 /*@only@*/ uentry 
315 makeCurrentParam (idDecl t)
316 {
317   uentry ue;
318
319   saveStoreLoc = fileloc_undefined;
320
321   /* param number unknown */
322
323   ue = uentry_makeParam (t, 0);
324   return ue;
325 }
326
327 ctype
328 declareUnnamedEnum (enumNameList el)
329 {
330   ctype ret = usymtab_enumEnumNameListType (el);
331   ctype rt;
332   uentry e;
333
334   if (ctype_isDefined (ret))
335     {
336       rt = ret;
337       e = uentry_makeEnumTagLoc (ctype_enumTag (rt), ret);
338
339       reflectStorageClass (e);
340       usymtab_supGlobalEntry (e);
341       
342       declareEnumList (el, ret, g_currentloc);    
343       enumNameList_free (el);
344     }
345   else
346     {
347       ctype ct = ctype_createEnum (fakeTag (), el);
348
349       e = uentry_makeEnumTagLoc (ctype_enumTag (ctype_realType (ct)), ct);
350       reflectStorageClass (e);
351
352       e = usymtab_supGlobalEntryReturn (e);
353       rt = uentry_getAbstractType (e);
354       declareEnumList (el, ct, g_currentloc);    
355     }
356   
357   return (rt);
358 }
359
360 ctype
361 declareEnum (cstring ename, enumNameList el)
362 {
363   ctype cet;
364   uentry e;
365
366   llassert (cstring_isDefined (ename));
367
368   cet = ctype_createEnum (ename, el);
369   e = uentry_makeEnumTagLoc (ename, cet);
370   reflectStorageClass (e);
371   e = usymtab_supGlobalEntryReturn (e);
372   cet = uentry_getType (e);
373   declareEnumList (el, cet, uentry_whereLast (e));    
374   return (uentry_getAbstractType (e));
375 }
376
377 static void
378 declareEnumList (enumNameList el, ctype c, fileloc loc)
379 {
380   bool boolnames = FALSE;
381   bool othernames = FALSE;
382
383   (void) context_getSaveLocation (); /* undefine it */
384
385   if (context_maybeSet (FLG_NUMENUMMEMBERS))
386     {
387       int maxnum = context_getValue (FLG_NUMENUMMEMBERS);
388       int num = enumNameList_size (el);
389
390       if (num > maxnum)
391         {
392           voptgenerror 
393             (FLG_NUMENUMMEMBERS,
394              message ("Enumerator %s declared with %d members (limit is set to %d)",
395                       ctype_unparse (c), num, maxnum),
396              loc);
397         }
398     }
399
400   enumNameList_elements (el, e)
401     {
402       uentry ue = usymtab_lookupExposeGlob (e);
403       ctype ct = uentry_getType (ue);
404
405       llassert (uentry_isEnumConstant (ue));
406
407       if (ctype_isUnknown (ct))
408         {
409           uentry_setType (ue, c);
410         }
411       else
412         {
413           if (cstring_equal (e, context_getFalseName ())
414               || cstring_equal (e, context_getTrueName ()))
415             {
416               if (othernames) 
417                 {
418                   if (optgenerror 
419                       (FLG_INCONDEFS,
420                        message ("Enumerator mixes boolean name (%s) with "
421                                 "non-boolean names",
422                                 e),
423                        uentry_whereLast (ue)))
424                     {
425                       ;
426                     }
427                 }
428               
429               boolnames = TRUE;
430               uentry_setType (ue, ctype_bool);
431               DPRINTF (("Set type: %s / %s",
432                         uentry_unparse (ue), ctype_unparse (ctype_bool)));
433             }
434           else 
435             {
436               if (boolnames) 
437                 {
438                   if (optgenerror 
439                       (FLG_INCONDEFS,
440                        message ("Enumerator mixes boolean names (%s, %s) with "
441                                 "non-boolean name: %s",
442                                 context_getTrueName (),
443                                 context_getFalseName (),
444                                 e),
445                        uentry_whereLast (ue)))
446                     {
447                       ;
448                     }
449                 }
450
451               othernames = TRUE;
452             }
453
454           if (!ctype_match (c, ct))
455             {
456               if (ctype_isDirectBool (ct))
457                 {
458                   if (cstring_equal (e, context_getFalseName ())
459                       || cstring_equal (e, context_getTrueName ()))
460                     {
461                       DPRINTF (("Here we are!"));
462                     }
463                   else
464                     {
465                       if (optgenerror 
466                           (FLG_INCONDEFS,
467                            message ("Enumerator member %s declared with "
468                                     "inconsistent type: %s",
469                                     e, ctype_unparse (c)),
470                            uentry_whereLast (ue)))
471                         {
472                           uentry_showWhereSpecifiedExtra 
473                             (ue, cstring_copy (ctype_unparse (ct)));
474                         }
475                     }
476                 }
477               else
478                 {
479                   if (optgenerror 
480                       (FLG_INCONDEFS,
481                        message ("Enumerator member %s declared with "
482                                 "inconsistent type: %s",
483                                 e, ctype_unparse (c)),
484                        uentry_whereLast (ue)))
485                     {
486                       uentry_showWhereSpecifiedExtra 
487                         (ue, cstring_copy (ctype_unparse (ct)));
488                     }
489                 }
490             }
491         }
492     } end_enumNameList_elements;
493 }
494
495 static /*@dependent@*/ uentryList currentParamList;
496
497 /*drl added 3-28-2002*/
498 /* this function takes a list of paramentar and generates a list
499    of constraints.
500 */
501
502 /* drl modified 10/23/2002
503
504 The current semantics are generated constraints of the form MaxSet(p) >= 0 and MaxRead(p) >= 0 for all pointers
505 unless the @out@ annotation has been applied to a parameter, then we only want to generate maxSet(p) > = 0
506 */
507
508 void setImplictfcnConstraints (void)
509 {
510   uentryList params;
511   sRef s;
512   constraint c;
513   params = currentParamList;
514
515   if (constraintList_isDefined (implicitFcnConstraints))
516     {
517       constraintList_free (implicitFcnConstraints);
518     }
519   
520   implicitFcnConstraints = constraintList_makeNew();
521   
522   uentryList_elements (params, el)
523     {
524       DPRINTF (("setImplictfcnConstraints doing: %s", uentry_unparse(el)));
525       
526       if (uentry_isVariable (el))
527         {
528           s = uentry_getSref(el);
529           
530           if (sRef_isReference (s))
531             {
532               DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) ));
533               /*drl 4/26/01
534                 chagned this from MaxSet(s) == 0 to MaxSet(s) >= 0 */
535               c = constraint_makeSRefWriteSafeInt (s, 0);
536               
537               implicitFcnConstraints = constraintList_add (implicitFcnConstraints , c);
538               
539               /*drl 10/23/2002 added support for out*/
540               
541               if (!uentry_isOut(el))
542                 {
543                   c = constraint_makeSRefReadSafeInt (s, 0);
544                   implicitFcnConstraints = constraintList_add (implicitFcnConstraints , c);
545                 }
546             }
547           else
548             {
549               DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) ));
550             }
551         } /*end uentry_isVariable*/
552       else if (uentry_isElipsisMarker (el) )      
553         {
554           /* just ignore these*/
555           ;
556         }
557       
558       else
559         {
560           /* just ignore this
561              I'm not sure if this is possible though
562           */
563           ;
564         }
565     } end_uentryList_elements;
566 }
567
568
569 /*@observer@*/ constraintList getImplicitFcnConstraints (void)
570 {
571   return implicitFcnConstraints;
572 }
573
574 void setCurrentParams (/*@dependent@*/ uentryList ue)
575 {
576   currentParamList = ue;
577 }
578
579 void clearCurrentParams (void)
580 {
581   currentParamList = uentryList_undefined;
582 }
583
584 /*
585 ** requires: uentry_isFunction (e)
586 **           parameter names for current function are in currentParamList
587 */
588
589 static void enterFunctionParams (uentryList params)
590 {
591   int paramno = 0;
592
593   uentryList_elements (params, current)
594     {
595       if (uentry_hasName (current)) 
596         {
597           uentry_setParamNo (current, paramno);
598           usymtab_supEntry (uentry_copy (current));
599         }
600       
601       paramno++;
602     } end_uentryList_elements; 
603 }
604  
605
606 extern void enterParamsTemp (void)
607 {
608   usymtab_enterScope ();
609   enterFunctionParams (currentParamList);
610 }
611
612 extern void exitParamsTemp (void)
613 {
614   usymtab_quietPlainExitScope ();
615 }
616
617 static /*@exposed@*/ uentry clabstract_globalDeclareFunction (idDecl tid) 
618 {
619   ctype deftype = idDecl_getCtype (tid);
620   ctype rettype;
621   uentry ue;
622   
623   DPRINTF (("Global function: %s", idDecl_unparse (tid)));
624
625   if (ctype_isFunction (deftype))
626     {
627       rettype = ctype_getReturnType (deftype);
628     }
629   else
630     {
631       rettype = ctype_unknown;
632     }
633
634   /*
635   ** check has been moved here...
636   */
637
638   if (ctype_isFunction (idDecl_getCtype (tid)))
639     {
640       ue = uentry_makeIdFunction (tid);
641       reflectSpecialCode (ue);
642       reflectArgsUsed (ue);
643       reflectStorageClass (ue);
644       uentry_checkParams (ue);
645       
646       DPRINTF (("Supercede function: %s", uentry_unparseFull (ue)));
647       
648       ue = usymtab_supGlobalEntryReturn (ue);
649       DPRINTF (("After supercede function: %s", uentry_unparseFull (ue)));
650       
651       DPRINTF (("Enter function: %s", uentry_unparseFull (ue)));
652       context_enterFunction (ue);
653       enterFunctionParams (uentry_getParams (ue));
654       
655       resetStorageClass ();
656       DPRINTF (("Function: %s", uentry_unparseFull (ue)));
657       return (ue);
658     }
659   else
660     {    
661       llparseerror (message ("Non-function declaration: %q",
662                              idDecl_unparse (tid)));
663       return (uentry_undefined);
664     }
665 }
666
667 /*
668 ** for now, no type checking
669 ** (must check later though!)
670 */
671
672 static /*@only@*/ uentry globalDeclareOldStyleFunction (idDecl tid)
673 {
674   uentry ue;
675
676   /*
677   ** check has been moved here...
678   */
679
680   if (cstring_equalLit (idDecl_observeId (tid), "main"))
681     {
682       context_setFlagTemp (FLG_MAINTYPE, FALSE);
683     }
684
685   ue = uentry_makeIdFunction (tid);
686   reflectStorageClass (ue);
687   reflectSpecialCode (ue);
688   reflectArgsUsed (ue);
689   uentry_setDefined (ue, g_currentloc);
690   uentry_checkParams (ue);
691   resetStorageClass ();
692
693   /* context_enterOldStyleScope (); */
694
695   return (ue);
696 }
697
698 static void oldStyleDeclareFunction (/*@only@*/ uentry e)
699 {
700   uentryList params = saveParamList;
701   ctype rt = uentry_getType (e);
702
703   llassert (ctype_isFunction (rt));
704
705   if (uentry_hasStateClauseList (e) 
706       || uentry_hasConditions (e))
707     {
708       llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
709                              fileloc_unparse (g_currentloc), uentry_unparse (e)));
710     }
711
712   e = usymtab_supGlobalEntryReturn (e);
713
714   context_enterFunction (e);
715   enterFunctionParams (params);
716   saveParamList = uentryList_undefined;
717   resetStorageClass ();
718 }
719
720 static void oldStyleCompleteFunction (/*@only@*/ uentry e)
721 {
722   uentryList params = saveParamList;
723   ctype rt = uentry_getType (e);
724
725   llassert (ctype_isFunction (rt));
726
727   if (uentry_hasStateClauseList (e) 
728       || uentry_hasConditions (e))
729     {
730       llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
731                              fileloc_unparse (g_currentloc), uentry_unparse (e)));
732     }
733
734   e = usymtab_supGlobalEntryReturn (e);
735
736   context_completeOldStyleFunction (e);
737   enterFunctionParams (params);
738   saveParamList = uentryList_undefined;
739   resetStorageClass ();
740 }
741
742 void clabstract_declareFunction (idDecl tid) /*@globals undef saveFunction; @*/
743 {
744   uentry ue;
745
746   DPRINTF (("Declare function: %s", idDecl_unparse (tid)));
747   
748   if (ctype_isUnknown (idDecl_getCtype (tid)))
749     {
750       /*
751       ** No type, its really a plain name (int) declaration
752       */
753
754       voptgenerror (FLG_IMPTYPE,
755                     message ("No type before declaration name (implicit int type): %q",
756                              idDecl_unparse (tid)),
757                     g_currentloc);
758       tid = idDecl_replaceCtype (tid, ctype_int);
759       processVariable (tid);
760       saveFunction = uentry_undefined;
761     }
762   else
763     {
764       if (s_processingParams)
765         {
766           ue = globalDeclareOldStyleFunction (tid);
767           saveFunction = ue;
768           DPRINTF (("Set save function: %s", uentry_unparseFull (ue)));
769         }
770       else
771         {
772           saveFunction = uentry_undefined;
773           
774           if (context_inRealFunction ())
775             {
776               ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
777               
778               llparseerror (message ("Function declared inside function: %q",
779                                      idDecl_unparse (tid)));
780               
781               context_quietExitFunction ();
782               ue = usymtab_supEntryReturn (ue);
783             }
784           else
785             {
786               if (context_inInnerScope ())
787                 {
788                   llparseerror (message ("Declaration in inner context: %q",
789                                          idDecl_unparse (tid)));
790                   
791                   sRef_setGlobalScope ();
792                   ue = uentry_makeVariableLoc (idDecl_observeId (tid), 
793                                                ctype_unknown);
794                   ue = usymtab_supGlobalEntryReturn (ue);
795                   sRef_clearGlobalScope ();
796                 }
797               else
798                 {
799                   ue = clabstract_globalDeclareFunction (tid);
800                 }
801             }
802           
803           resetGlobals ();
804         }
805
806       resetStorageClass ();
807     }
808
809   idDecl_free (tid);
810 }
811
812 void declareStaticFunction (idDecl tid) /*@globals undef saveFunction; @*/
813 {
814   uentry ue;
815
816   DPRINTF (("Declare static funciton: %s", idDecl_unparse (tid)));
817
818   if (s_processingParams)
819     {
820       ue = globalDeclareOldStyleFunction (tid);
821       saveFunction = ue;
822     }
823   else
824     {
825       saveFunction = uentry_undefined;
826
827       if (context_inRealFunction ())
828         {
829           ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
830
831           llparseerror (message ("Function declared inside function: %q",
832                                  idDecl_unparse (tid)));
833           
834           context_quietExitFunction ();
835           ue = usymtab_supEntryReturn (ue);
836         }
837       else
838         {
839           if (context_inInnerScope ())
840             {
841               llparseerror (message ("Declaration in inner context: %q",
842                                      idDecl_unparse (tid)));
843               
844               sRef_setGlobalScope ();
845               ue = uentry_makeVariableLoc (idDecl_observeId (tid), 
846                                            ctype_unknown);
847               ue = usymtab_supGlobalEntryReturn (ue);
848               sRef_clearGlobalScope ();
849             }
850           else
851             {
852               ctype deftype = idDecl_getCtype (tid);
853               ctype rettype;
854               
855               if (ctype_isFunction (deftype))
856                 {
857                   rettype = ctype_getReturnType (deftype);
858                 }
859               else
860                 {
861                   rettype = ctype_unknown;
862                 }
863               
864               /*
865               ** check has been moved here...
866               */
867               
868               if (ctype_isFunction (idDecl_getCtype (tid)))
869                 {
870                   ue = uentry_makeIdFunction (tid);
871                   reflectSpecialCode (ue);
872                   reflectArgsUsed (ue);
873                 }
874               else
875                 {    
876                   DPRINTF (("Here we are!"));
877                   llparseerror (message ("Inconsistent function declaration: %q",
878                                          idDecl_unparse (tid)));
879                   
880                   tid = idDecl_replaceCtype 
881                     (tid, ctype_makeFunction (ctype_unknown, uentryList_undefined));
882                   ue = uentry_makeIdFunction (tid);
883                 }
884               
885               reflectStorageClass (ue);
886               uentry_setStatic (ue);
887
888               uentry_checkParams (ue);
889         
890               DPRINTF (("Sub global entry: %s", uentry_unparse (ue)));
891               ue = usymtab_supGlobalEntryReturn (ue);
892
893               context_enterFunction (ue);
894               enterFunctionParams (uentry_getParams (ue));
895               resetStorageClass ();
896             }
897         }
898       
899       resetGlobals ();
900     }
901   
902   resetStorageClass ();
903   idDecl_free (tid);
904 }
905
906 void
907 checkTypeDecl (uentry e, ctype rep)
908 {
909   cstring n = uentry_getName (e);
910
911   DPRINTF (("Check type decl: %s", uentry_unparseFull (e)));
912
913   if (cstring_equal (context_getBoolName (), n))
914     {
915       ctype rrep = ctype_realType (rep);
916       
917       /*
918       ** for abstract enum types, we need to fix the enum members:
919       ** they should have the abstract type, not the rep type.
920       */
921       
922       if (ctype_isEnum (ctype_realType (rrep)))
923         {
924           enumNameList el = ctype_elist (rrep);
925           
926           enumNameList_elements (el, ye)
927             {
928               if (usymtab_existsGlob (ye))
929                 {
930                   uentry ue = usymtab_lookupSafe (ye);
931                   uentry_setType (ue, ctype_bool);
932                 }
933
934               if (cstring_equal (context_getTrueName (), ye)
935                   || cstring_equal (context_getFalseName (), ye))
936                 {
937                   ;
938                 }
939               else
940                 {
941                   vgenhinterror 
942                     (FLG_SYNTAX,
943                      message ("Member of boolean enumerated type definition "
944                               "does not match name set to represent true "
945                               "or false: %s",
946                               ye),
947                      message ("Use -boolfalse and -booltrue to set the "
948                               "name of false and true boolean values."),
949                      uentry_whereDefined (e));
950                 }
951             } end_enumNameList_elements;
952         }
953     }
954
955   if (usymtab_exists (n))
956     {
957       usymId llm = usymtab_getId (n);
958       uentry le  = usymtab_getTypeEntry (typeId_fromUsymId (llm));
959
960       uentry_setDeclared (e, g_currentloc); 
961       uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le), stateInfo_currentLoc ()));
962
963       DPRINTF (("Here we are: %s / %s",
964                 n, context_getBoolName ()));
965       
966       if (uentry_isAbstractDatatype (le))
967         {
968           ctype rrep = ctype_realType (rep);
969
970           DPRINTF (("Abstract type: %s", uentry_unparseFull (le)));
971
972           /*
973           ** for abstract enum types, we need to fix the enum members:
974           ** they should have the abstract type, not the rep type.
975           */
976
977           if (ctype_isEnum (ctype_realType (rrep)))
978             {
979               ctype at = uentry_getAbstractType (le);
980               enumNameList el = ctype_elist (rrep);
981
982               enumNameList_elements (el, ye)
983                 {
984                   if (usymtab_existsGlob (ye))
985                     {
986                       uentry ue = usymtab_lookupSafe (ye);
987
988                       llassert (uentry_isEitherConstant (ue));
989
990                       /* evans 2002-04-22 */
991                       if (ctype_isBool (uentry_getType (ue)))
992                         {
993                           /*
994                           ** If set using -booltrue or -boolfalse, don't change the type.
995                           */
996                         }
997                       else
998                         {
999                           llassertprint (ctype_match (uentry_getType (ue), rrep),
1000                                          ("Bad enum: %s / %s",
1001                                           uentry_unparse (ue),
1002                                           ctype_unparse (rrep)));
1003                           
1004                           uentry_setType (ue, at);
1005                         }
1006                     }
1007                 } end_enumNameList_elements;
1008             }
1009           
1010           if (uentry_isMutableDatatype (le))
1011             {
1012               /* maybe more complicated if abstract and immutable ? */
1013
1014               if (!ctype_isRealPointer (rep) && !ctype_isRealAbstract (rep))
1015                 {
1016                   voptgenerror 
1017                     (FLG_MUTREP,
1018                      message ("Mutable abstract type %s declared without pointer "
1019                               "indirection: %s (violates assignment semantics)",
1020                               n, ctype_unparse (rep)),
1021                      uentry_whereDefined (e));
1022                   
1023                   uentry_setMutable (e);
1024                 }
1025             }
1026         }
1027     }
1028   else
1029     {
1030       fileloc fl = uentry_whereDeclared (e);
1031
1032       if (context_getFlag (FLG_LIKELYBOOL)
1033           && !context_getFlag (FLG_BOOLINT))
1034         {
1035           if ((cstring_equalLit (n, "BOOL")
1036                || cstring_equalLit (n, "Bool")
1037                || cstring_equalLit (n, "bool")
1038                || cstring_equalLit (n, "boolean")
1039                || cstring_equalLit (n, "Boolean")
1040                || cstring_equalLit (n, "BOOLEAN"))
1041               && !(cstring_equal (n, context_getBoolName ())))
1042             {
1043               if (context_setBoolName ()) {
1044                 voptgenerror 
1045                   (FLG_LIKELYBOOL,
1046                    message ("Type %s is probably meant as a boolean type, but does "
1047                             "not match the boolean type name \"%s\".",
1048                             n,
1049                             context_getBoolName ()),
1050                    fl);
1051               } else
1052                 voptgenerror 
1053                   (FLG_LIKELYBOOL,
1054                    message ("Type %s is probably meant as a boolean type, "
1055                             "but the boolean type name is not set. "
1056                             "Use -booltype %s to set it.",
1057                             n,
1058                             n),
1059                    fl);
1060                 }
1061         }
1062
1063       if (!uentry_isStatic (e)
1064           && !ctype_isFunction (uentry_getType (e)) 
1065           && !fileloc_isLib (fl) 
1066           && !fileloc_isImport (fl)
1067           && fileloc_isHeader (fl))
1068         {
1069           voptgenerror (FLG_EXPORTTYPE,
1070                         message ("Type exported, but not specified: %s\n", n),
1071                         fl);
1072         }
1073     }
1074
1075   cstring_free (n);
1076 }
1077
1078 uentryList
1079 fixUentryList (idDeclList tl, qtype q)
1080 {
1081   uentryList f = uentryList_new ();
1082   
1083   idDeclList_elements (tl, i)
1084   {
1085     if (idDecl_isDefined (i))
1086       {
1087         uentry ue;
1088         uentry old;
1089         ctype rt;
1090
1091         (void) idDecl_fixBase (i, q);
1092
1093         /*
1094         ** implicit annotations 
1095         */
1096
1097         (void) fixStructDecl (i);
1098
1099         ue = uentry_makeIdVariable (i);
1100         rt = ctype_realType (uentry_getType (ue));
1101
1102         /*
1103         ** where is this here???
1104
1105         if (ctype_isArray (rt) || ctype_isSU (rt))
1106           {
1107             sRef_setAllocated (uentry_getSref (ue), uentry_whereDefined (ue));
1108           }
1109
1110         **
1111         */
1112
1113         if (uentry_isValid (old = uentryList_lookupField (f, uentry_rawName (ue))))
1114           {
1115             if (optgenerror (FLG_SYNTAX,
1116                              message ("Field name reused: %s", uentry_rawName (ue)),
1117                              uentry_whereDefined (ue)))
1118               {
1119                 llgenmsg (message ("Previous use of %s", uentry_rawName (ue)),
1120                           uentry_whereDefined (old));
1121               }
1122           }
1123         
1124         f = uentryList_add (f, ue);
1125       }
1126   } end_idDeclList_elements;
1127
1128   idDeclList_free (tl);
1129   return (f);
1130 }
1131
1132 /*
1133 ** This is a hack to support unnamed struct/union fields as done by
1134 ** Microsoft VC++.  It is not supported by the ANSI standard.  
1135 **
1136 ** The inner fields are added to the outer structure.  This is meaningful
1137 ** for nesting structs inside unions, but Splint does no related 
1138 ** checking.
1139 */
1140
1141 uentryList
1142 fixUnnamedDecl (qtype q)
1143 {
1144   ctype ct = ctype_realType (qtype_getType (q));
1145
1146   if (ctype_isStruct (ct) || ctype_isUnion (ct))
1147     {
1148       return uentryList_single (uentry_makeUnnamedVariable (ct));
1149     }
1150   else if (ctype_isEnum (ct))
1151     {
1152       /* evans 2002-02-05: nothing to do for unnamed enum lists */
1153       return uentryList_undefined;
1154     }
1155   else
1156     { 
1157       voptgenerror 
1158         (FLG_SYNTAX,
1159          message ("Type name in field declarations: %s", qtype_unparse (q)),
1160          g_currentloc);
1161     }
1162
1163   return uentryList_undefined;
1164 }
1165
1166 void setStorageClass (storageClassCode sc)
1167 {
1168   storageClass = sc;
1169 }
1170
1171 void
1172 setProcessingIterVars (uentry iter)
1173 {
1174   s_processingIterVars = TRUE;
1175   currentIter = iter;
1176   saveIterParamNo = 0;
1177 }
1178
1179 void
1180 setProcessingGlobalsList ()
1181 {
1182   s_processingGlobals = TRUE;
1183   fcnNoGlobals = FALSE;
1184 }
1185
1186 static bool ProcessingGlobMods = FALSE;
1187
1188 void
1189 setProcessingGlobMods ()
1190 {
1191   ProcessingGlobMods = TRUE;
1192 }
1193
1194 void
1195 clearProcessingGlobMods ()
1196 {
1197   ProcessingGlobMods = FALSE;
1198 }
1199
1200 bool
1201 isProcessingGlobMods ()
1202 {
1203   return (ProcessingGlobMods);
1204 }
1205
1206 static void resetGlobals (void)
1207 {
1208   s_processingGlobals = FALSE;
1209   fcnNoGlobals = FALSE;
1210 }
1211
1212 void
1213 unsetProcessingGlobals ()
1214 {
1215   s_processingGlobals = FALSE;
1216 }
1217
1218 void
1219 setProcessingVars (/*@only@*/ qtype q)
1220 {
1221   s_processingVars = TRUE;
1222   qtype_free (processingType);
1223   processingType = q;
1224 }
1225
1226 static void
1227 setGenericParamList (/*@dependent@*/ uentryList pm)
1228 {
1229   s_processingParams = TRUE;
1230   saveParamList = pm;
1231 }
1232
1233 void
1234 setProcessingTypedef (qtype q)
1235 {
1236   s_processingTypedef = TRUE;
1237
1238   qtype_free (processingType);
1239   processingType = q;
1240 }
1241
1242 void
1243 unsetProcessingVars ()
1244 {
1245   resetStorageClass ();
1246   s_processingVars = FALSE;
1247 }
1248
1249 void 
1250 oldStyleDoneParams ()
1251 {  
1252   if (s_processingParams)
1253     {
1254       if (uentry_isInvalid (saveFunction))
1255         {
1256           llbuglit ("unsetProcessingVars: no saved function\n");
1257         }
1258       else
1259         {
1260           ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
1261           uentryList params = uentryList_copy (saveParamList);
1262           ctype ct2 = ctype_makeFunction (ct, params);
1263
1264           uentry_setType (saveFunction, ct2);
1265           s_processingParams = FALSE;
1266
1267           oldStyleCompleteFunction (saveFunction);
1268           saveFunction = uentry_undefined;
1269           resetGlobals ();
1270         }
1271     }
1272   else
1273     {
1274       /*
1275       ** If the paramlist used a type name, we could be here.
1276       */
1277
1278       llfatalerror (message ("%q: Old-style function parameter list uses a "
1279                              "type name.", fileloc_unparse (g_currentloc)));
1280     }
1281 }
1282
1283 void 
1284 checkDoneParams ()
1285 {
1286   if (uentry_isValid (saveFunction))
1287     {
1288       /*
1289       ** old style declaration
1290       */
1291
1292       ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
1293       ctype ct2;
1294
1295       DPRINTF (("save function: %s", uentry_unparseFull (saveFunction)));
1296
1297       uentryList_elements (saveParamList, current)
1298         {
1299           uentry_setType (current, ctype_int); /* all params are ints */
1300         } end_uentryList_elements; 
1301
1302       ct2 = ctype_makeParamsFunction (ct, uentryList_copy (saveParamList));
1303       
1304       uentry_setType (saveFunction, ct2);
1305       s_processingParams = FALSE;
1306       
1307       oldStyleDeclareFunction (saveFunction);
1308       saveFunction = uentry_undefined;
1309     }
1310 }
1311
1312 void clabstract_declareType (/*@only@*/ exprNodeList decls, /*@only@*/ warnClause warn)
1313 {
1314   llassert (s_processingTypedef);
1315
1316   DPRINTF (("Declare type: %s", exprNodeList_unparse (decls)));
1317
1318   if (warnClause_isDefined (warn))
1319     {
1320       DPRINTF (("Has a warn clause!"));
1321       DPRINTF (("Warn: %s", warnClause_unparse (warn)));
1322
1323       exprNodeList_elements (decls, el)
1324         {
1325           uentry ue = exprNode_getUentry (el);
1326           cstring uname = uentry_getName (ue);
1327
1328           DPRINTF (("Entry: %s", exprNode_unparse (el)));
1329
1330           /*
1331           ** Need to lookup again to make sure we have the right one...
1332           */
1333
1334           ue = usymtab_lookupExposeGlob (uname);
1335
1336           llassert (uentry_isValid (ue));
1337           llassert (uentry_isDatatype (ue));
1338
1339           DPRINTF (("Warning for %s: %s",
1340                     uentry_unparse (ue), warnClause_unparse (warn)));
1341
1342           uentry_addWarning (ue, warnClause_copy (warn));
1343           DPRINTF (("After add warning: %s", uentry_unparseFull (ue)));
1344           cstring_free (uname);
1345         } end_exprNodeList_elements;
1346     }
1347
1348   warnClause_free (warn);
1349   exprNodeList_free (decls);
1350   unsetProcessingTypedef ();
1351 }
1352
1353 void
1354 unsetProcessingTypedef ()
1355 {
1356   s_processingTypedef = FALSE;
1357 }
1358
1359 void checkConstant (qtype t, idDecl id) 
1360 {
1361   uentry e;
1362   
1363   id = idDecl_fixBase (id, t);
1364   e = uentry_makeIdConstant (id);
1365   
1366   reflectStorageClass (e);
1367   resetStorageClass ();
1368
1369   DPRINTF (("Constant: %s", uentry_unparseFull (e)));
1370   usymtab_supGlobalEntry (e);
1371 }
1372
1373 void checkValueConstant (qtype t, idDecl id, exprNode e) 
1374 {
1375   uentry ue;
1376
1377   id = idDecl_fixBase (id, t);
1378   ue = uentry_makeIdConstant (id);
1379   reflectStorageClass (ue);
1380   resetStorageClass ();
1381
1382   if (exprNode_isDefined (e))
1383     {
1384       if (!exprNode_matchType (uentry_getType (ue), e))
1385         {
1386           (void) gentypeerror 
1387             (exprNode_getType (e), e,
1388              uentry_getType (ue), exprNode_undefined,
1389              message ("Constant %q initialized to type %t, expects %t: %s",
1390                       uentry_getName (ue),  
1391                       exprNode_getType (e), 
1392                       uentry_getType (ue),
1393                       exprNode_unparse (e)),
1394              exprNode_loc (e));
1395         }
1396       else
1397         {
1398           if (exprNode_hasValue (e))
1399             {
1400               uentry_mergeConstantValue (ue, multiVal_copy (exprNode_getValue (e)));
1401             }
1402           else
1403             {
1404               DPRINTF (("No value: %s", exprNode_unparse (e)));
1405             }
1406         }
1407     }
1408
1409   DPRINTF (("Constant value: %s", uentry_unparseFull (ue)));
1410   usymtab_supGlobalEntry (ue);
1411 }
1412
1413 static void processVariable (idDecl t)
1414 {
1415   uentry e;
1416   ctype ct;
1417   
1418   ct = ctype_realType (idDecl_getCtype (t));
1419   
1420   if (s_processingParams)
1421     {
1422       cstring id = idDecl_getName (t);
1423       int paramno = uentryList_lookupRealName (saveParamList, id);
1424       
1425       if (paramno >= 0)
1426         {
1427           uentry cparam = uentryList_getN (saveParamList, paramno);
1428           
1429           DPRINTF (("Processing param: %s", uentry_unparseFull (cparam)));
1430           uentry_setType (cparam, idDecl_getCtype (t));
1431           uentry_reflectQualifiers (cparam, idDecl_getQuals (t));
1432           uentry_setDeclaredOnly (cparam, context_getSaveLocation ());
1433           DPRINTF (("Processing param: %s", uentry_unparseFull (cparam)));
1434         }
1435       else
1436         {
1437           llfatalerrorLoc
1438             (message ("Old style declaration uses unlisted parameter: %s", 
1439                       id));
1440         }
1441     }
1442   else
1443     {
1444       fileloc loc;
1445       
1446       if (context_inIterDef ())
1447         {
1448           cstring pname = makeParam (idDecl_observeId (t));
1449           uentry p = usymtab_lookupSafe (pname);
1450           
1451           cstring_free (pname);
1452           
1453           if (uentry_isYield (p))
1454             {
1455               e = uentry_makeParam (t, sRef_getParam (uentry_getSref (p)));
1456               uentry_checkYieldParam (p, e);
1457               usymtab_supEntrySref (e);
1458               return;
1459             }
1460         }
1461       
1462       if ((hasSpecialCode () || argsUsed)
1463           && ctype_isFunction (idDecl_getCtype (t)))
1464         {
1465           e = uentry_makeIdFunction (t);
1466           reflectSpecialCode (e);
1467           reflectArgsUsed (e);
1468         }
1469       else
1470         {
1471           e = uentry_makeIdVariable (t);
1472         }
1473       
1474       loc = uentry_whereDeclared (e);
1475       
1476       /*
1477         if (context_inGlobalScope ())
1478         {
1479         uentry_checkParams was here!
1480         }
1481       */
1482       
1483       if (ctype_isFunction (uentry_getType (e)))
1484         {
1485           clabstract_prepareFunction (e);
1486         }
1487       
1488       DPRINTF (("Superceding... %s", uentry_unparseFull (e)));
1489       e = usymtab_supEntrySrefReturn (e);
1490       DPRINTF (("After superceding... %s", uentry_unparseFull (e)));      
1491       
1492       if (uentry_isExtern (e) && !context_inGlobalScope ())
1493         {
1494           voptgenerror 
1495             (FLG_NESTEDEXTERN,
1496              message ("Declaration using extern inside function scope: %q",
1497                       uentry_unparse (e)),
1498              g_currentloc);
1499           
1500           uentry_setDefined (e, fileloc_getExternal ());
1501           sRef_setDefined (uentry_getSref (e), fileloc_getExternal ());
1502         }
1503       
1504       if (uentry_isFunction (e))
1505         {
1506           if (!context_inXHFile ())
1507             {
1508               checkParamNames (e);
1509             }
1510         }
1511       
1512       if (uentry_isVar (e) && uentry_isCheckedUnknown (e))
1513         {
1514           sRef sr = uentry_getSref (e);
1515           
1516           if (sRef_isLocalVar (sr))
1517             {
1518               if (context_getFlag (FLG_IMPCHECKMODINTERNALS))
1519                 {
1520                   uentry_setCheckMod (e);
1521                 }
1522               else
1523                 {
1524                   uentry_setUnchecked (e);
1525                 }
1526             }
1527           else if (sRef_isFileStatic (sr))
1528             {
1529               if (context_getFlag (FLG_IMPCHECKEDSTRICTSTATICS))
1530                 {
1531                   uentry_setCheckedStrict (e);
1532                 }
1533               else if (context_getFlag (FLG_IMPCHECKEDSTATICS))
1534                 {
1535                   uentry_setChecked (e);
1536                 }
1537               else if (context_getFlag (FLG_IMPCHECKMODSTATICS))
1538                 {
1539                   uentry_setCheckMod (e);
1540                 }
1541               else
1542                 {
1543                   ;
1544                 }
1545             }
1546           else /* real global */
1547             {
1548               llassert (sRef_isRealGlobal (sr));
1549               
1550               if (context_getFlag (FLG_IMPCHECKEDSTRICTGLOBALS))
1551                 {
1552                   uentry_setCheckedStrict (e);
1553                 }
1554               else if (context_getFlag (FLG_IMPCHECKEDGLOBALS))
1555                 {
1556                   uentry_setChecked (e);
1557                 }
1558               else if (context_getFlag (FLG_IMPCHECKMODGLOBALS))
1559                 {
1560                   uentry_setCheckMod (e);
1561                 }
1562               else
1563                 {
1564                   ;
1565                 }
1566             }
1567         }
1568     }
1569 }
1570
1571 void processNamedDecl (idDecl t)
1572 {
1573   if (qtype_isUndefined (processingType))
1574     {
1575       processingType = qtype_create (ctype_int);
1576       t = idDecl_fixBase (t, processingType);
1577
1578       voptgenerror (FLG_IMPTYPE,
1579                     message ("No type before declaration name (implicit int type): %q",
1580                              idDecl_unparse (t)),
1581                     g_currentloc);
1582     }
1583   else
1584     {
1585       t = idDecl_fixBase (t, processingType);
1586     }
1587
1588   DPRINTF (("Declare: %s", idDecl_unparse (t)));
1589   
1590   if (s_processingGlobals)
1591     {
1592       cstring id = idDecl_getName (t);
1593       uentry ue = usymtab_lookupSafe (id);
1594       
1595       if (!uentry_isValid (ue))
1596         {
1597           llerror (FLG_UNRECOG,
1598                    message ("Variable used in globals list is undeclared: %s", id));
1599         }
1600       else
1601         {
1602           if (!ctype_match (uentry_getType (ue), idDecl_getCtype (t)))
1603             {
1604               voptgenerror 
1605                 (FLG_INCONDEFS,
1606                  message ("Variable %s used in globals list declared %s, "
1607                           "but listed as %s", 
1608                           id, ctype_unparse (uentry_getType (ue)), 
1609                           ctype_unparse (idDecl_getCtype (t))),
1610                  g_currentloc);
1611             }
1612           else
1613             {
1614               sRef sr = sRef_copy (uentry_getSref (ue));
1615               reflectGlobalQualifiers (sr, idDecl_getQuals (t));
1616             }
1617         }
1618     }
1619   else if (s_processingVars)
1620     {
1621       processVariable (t);
1622     }
1623   else if (s_processingTypedef)
1624     {
1625       ctype ct = idDecl_getCtype (t);
1626       uentry e;
1627       
1628       DPRINTF (("Processing typedef: %s", ctype_unparse (ct)));
1629       
1630       e = uentry_makeIdDatatype (t);
1631
1632       if (cstring_equal (idDecl_getName (t), context_getBoolName ())) {
1633         ctype rt = ctype_realType (ct);
1634         
1635         if (ctype_isEnum (rt)) {
1636           ;
1637         } else {
1638           if (!(ctype_isInt (rt)
1639                 || ctype_isUnknown (rt)
1640                 || ctype_isChar (rt))) {
1641             (void) llgenerror
1642               (FLG_BOOLTYPE, 
1643                message ("Boolean type %s defined using non-standard type %s (integral, char or enum type expected)",
1644                         context_getBoolName (),
1645                         ctype_unparse (ct)),
1646                uentry_whereLast (e));
1647           }
1648           
1649           ct = ctype_bool;
1650           uentry_setType (e, ct);
1651         }
1652       }
1653
1654       reflectStorageClass (e);
1655       checkTypeDecl (e, ct);
1656       
1657       e = usymtab_supReturnTypeEntry (e);
1658     }
1659   else
1660     {
1661       llparseerror (message ("Suspect missing struct or union keyword: %q",
1662                              idDecl_unparse (t)));
1663     }
1664
1665   }
1666
1667 /*
1668 ** moved from grammar
1669 */
1670
1671 static idDecl fixStructDecl (/*@returned@*/ idDecl d)
1672 {
1673   if (ctype_isVisiblySharable (idDecl_getCtype (d)) 
1674       && context_getFlag (FLG_STRUCTIMPONLY))
1675     {
1676       if (!qualList_hasAliasQualifier (idDecl_getQuals (d)))
1677         {
1678           if (qualList_hasExposureQualifier (idDecl_getQuals (d)))
1679             {
1680               idDecl_addQual (d, qual_createDependent ());
1681             }
1682           else
1683             {
1684               idDecl_addQual (d, qual_createImpOnly ());
1685             }
1686         }
1687     }
1688
1689   return d;
1690 }
1691
1692 ctype
1693 declareUnnamedStruct (/*@only@*/ uentryList f)
1694 {
1695   DPRINTF (("Unnamed struct: %s", uentryList_unparse (f)));
1696
1697   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1698     {
1699       int num = uentryList_size (f);
1700       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1701
1702       if (num > max)
1703         {
1704           voptgenerror 
1705             (FLG_NUMSTRUCTFIELDS,
1706              message ("Structure declared with %d fields "
1707                       "(limit is set to %d)",
1708                       num, max),
1709              g_currentloc);
1710         }
1711     }
1712
1713   return (ctype_createUnnamedStruct (f));
1714 }
1715
1716 ctype
1717 declareUnnamedUnion (/*@only@*/ uentryList f)
1718 {
1719   DPRINTF (("Unnamed union: %s", uentryList_unparse (f)));
1720
1721   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1722     {
1723       int num = uentryList_size (f);
1724       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1725
1726       if (num > max)
1727         {
1728           voptgenerror 
1729             (FLG_NUMSTRUCTFIELDS,
1730              message ("Union declared with %d fields "
1731                       "(limit is set to %d)",
1732                       num, max),
1733              g_currentloc);
1734         }
1735     }
1736
1737   return (ctype_createUnnamedUnion (f));
1738 }
1739
1740 ctype declareStruct (cstring id, /*@only@*/ uentryList f)
1741 {
1742   ctype ct; 
1743   uentry ue;
1744   int num = uentryList_size (f);
1745
1746   DPRINTF (("Declare struct: %s / %s [%d]", id, uentryList_unparse (f),
1747             uentryList_size (f)));
1748
1749   ct = ctype_createStruct (cstring_copy (id), f);
1750
1751   DPRINTF (("Ctype: %s", ctype_unparse (ct)));
1752
1753   ue = uentry_makeStructTagLoc (id, ct);
1754
1755   DPRINTF (("ue: %s", uentry_unparseFull (ue)));
1756
1757   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1758     {
1759       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1760
1761       if (num > max)
1762         {
1763           voptgenerror 
1764             (FLG_NUMSTRUCTFIELDS,
1765              message ("Structure %q declared with %d fields "
1766                       "(limit is set to %d)",
1767                       uentry_getName (ue), num, max),
1768              uentry_whereLast (ue));
1769         }
1770     }
1771
1772   return (usymtab_supTypeEntry (ue));
1773 }
1774
1775 ctype declareUnion (cstring id, uentryList f)
1776 {
1777   ctype ct; 
1778   uentry ue;
1779   int num = uentryList_size (f);
1780
1781   ct = ctype_createUnion (cstring_copy (id), f);
1782   ue = uentry_makeUnionTagLoc (id, ct);
1783
1784   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1785     {
1786       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1787
1788       if (num > max)
1789         {
1790           voptgenerror 
1791             (FLG_NUMSTRUCTFIELDS,
1792              message ("Union %q declared with %d fields "
1793                       "(limit is set to %d)",
1794                       uentry_getName (ue), num, max),
1795              uentry_whereLast (ue));
1796         }
1797     }
1798
1799   return (usymtab_supTypeEntry (ue));
1800 }
1801
1802 ctype handleStruct (/*@only@*/ cstring id)
1803 {
1804   if (usymtab_existsStructTag (id))
1805     {
1806       ctype ct = uentry_getAbstractType (usymtab_lookupStructTag (id));
1807
1808       cstring_free (id);
1809       return ct;
1810     }
1811   else
1812     {
1813       return (ctype_createForwardStruct (id));
1814     }
1815 }
1816
1817 ctype handleUnion (/*@only@*/ cstring id)
1818 {
1819   if (usymtab_existsUnionTag (id))
1820     {
1821       ctype ret = uentry_getAbstractType (usymtab_lookupUnionTag (id));
1822       cstring_free (id);
1823       return (ret);
1824     }
1825   else
1826     {
1827       return (ctype_createForwardUnion (id));
1828     }
1829 }
1830
1831 ctype
1832 handleEnum (cstring id)
1833 {
1834   if (usymtab_existsEnumTag (id))
1835     {
1836       ctype ret = uentry_getAbstractType (usymtab_lookupEnumTag (id));
1837       cstring_free (id);
1838       return ret;
1839     }
1840   else
1841     {
1842       return (ctype_createForwardEnum (id));
1843     }
1844 }
1845
1846 bool processingIterVars (void) 
1847
1848   return s_processingIterVars; 
1849 }
1850
1851 uentry getCurrentIter (void) 
1852 {
1853   return currentIter; 
1854 }
1855
1856 static bool flipOldStyle = FALSE;
1857 static bool flipNewStyle = TRUE;
1858
1859 void setFlipOldStyle ()          { flipOldStyle = TRUE; }
1860 bool isFlipOldStyle ()           { return flipOldStyle; }
1861 bool isNewStyle ()               { return flipNewStyle; }
1862 void setNewStyle ()              { flipNewStyle = TRUE; }
1863
1864 /*@dependent@*/ uentryList handleParamIdList (/*@dependent@*/ uentryList params)
1865 {  
1866   int paramno = 0;
1867
1868   /*
1869   ** this is a really YUCKY hack to handle old style
1870   ** declarations.
1871   */
1872   
1873   voptgenerror (FLG_OLDSTYLE,
1874                 cstring_makeLiteral ("Old style function declaration"),
1875                 g_currentloc); 
1876
1877   DPRINTF (("Handle old style params: %s", uentryList_unparseFull (params)));
1878
1879   uentryList_elements (params, current)
1880     {
1881       uentry_setParam (current);
1882       uentry_setSref (current, sRef_makeParam 
1883                       (paramno, ctype_unknown, 
1884                        stateInfo_makeLoc (uentry_whereLast (current), SA_DECLARED)));
1885       paramno++;
1886     } end_uentryList_elements;
1887
1888   setGenericParamList (params);
1889   cscannerHelp_setExpectingTypeName ();
1890
1891   return params;
1892 }
1893
1894 /*@dependent@*/ uentryList handleParamTypeList (/*@returned@*/ uentryList params)
1895 {
1896   if (flipOldStyle)
1897     {
1898       uentryList_fixMissingNames (params);
1899
1900       voptgenerror (FLG_OLDSTYLE, 
1901                     cstring_makeLiteral ("Old style function declaration."), 
1902                     g_currentloc); 
1903       
1904       setGenericParamList (params);
1905       flipOldStyle = FALSE;
1906       cscannerHelp_setExpectingTypeName ();
1907     }
1908  
1909   return (params); 
1910 }
1911
1912 void
1913 doVaDcl ()
1914 {
1915   ctype c = ctype_unknown;
1916   cstring id = cstring_makeLiteral ("va_alist");
1917   uentry e;
1918
1919   if (s_processingParams)
1920     {
1921       int i = uentryList_lookupRealName (saveParamList, id);
1922       
1923       if (i >= 0)
1924         {
1925           fileloc loc = context_getSaveLocation ();
1926           e = uentry_makeVariableSrefParam 
1927             (id, c, loc, 
1928              sRef_makeParam (i, c, stateInfo_makeLoc (loc, SA_DECLARED)));
1929         }
1930       else
1931         {
1932           e = uentry_undefined; /* suppress gcc message */
1933           llfatalerrorLoc (cstring_makeLiteral ("va_dcl used without va_alist"));
1934         }
1935     }
1936   else
1937     {    
1938       llerror (FLG_SYNTAX, cstring_makeLiteral ("va_dcl used outside of function declaration"));
1939       e = uentry_makeVariableLoc (id, c);
1940     }
1941
1942   cstring_free (id);
1943   uentry_setUsed (e, g_currentloc);  
1944   usymtab_supEntrySref (e);
1945 }
1946
1947 /*@exposed@*/ sRef modListPointer (/*@exposed@*/ sRef s)
1948 {
1949   ctype ct = sRef_getType (s);
1950   ctype rt = ctype_realType (ct);
1951   
1952   if (ctype_isAP (rt))
1953     {
1954       if (context_inHeader () && ctype_isAbstract (ct))
1955         {
1956           voptgenerror 
1957             (FLG_ABSTRACT,
1958              message
1959              ("Modifies clause in header file dereferences abstract "
1960               "type %s (interface modifies clause should not depend "
1961               "on or expose type representation): %q",
1962               ctype_unparse (ct),
1963               sRef_unparse (s)),
1964              g_currentloc);
1965         }
1966
1967       return (sRef_constructPointer (s));
1968     }
1969   else
1970     {
1971       if (ctype_isKnown (rt))
1972         {
1973           voptgenerror 
1974             (FLG_TYPE,
1975              message ("Implementation modifies clause dereferences non-pointer (type %s): %q",
1976                       ctype_unparse (rt),
1977                       sRef_unparse (s)),
1978              g_currentloc);
1979         }
1980
1981       return s;
1982     }
1983 }
1984
1985 /*@exposed@*/ sRef modListFieldAccess (sRef s, cstring f)
1986 {
1987   ctype ct = sRef_getType (s);
1988   ctype rt = ctype_realType (ct);
1989   
1990   if (ctype_isStructorUnion (rt))
1991     {
1992       uentry tf = uentryList_lookupField (ctype_getFields (rt), f);
1993       
1994       if (uentry_isUndefined (tf))
1995         {
1996           voptgenerror (FLG_TYPE,
1997                         message ("Modifies list accesses non-existent "
1998                                  "field %s of %t: %q", f, ct, 
1999                                  sRef_unparse (s)),
2000                         g_currentloc);
2001           
2002           cstring_free (f);
2003           return sRef_undefined;
2004         }
2005       else 
2006         {
2007           if (ctype_isAbstract (ct) && context_inHeader ())
2008             {
2009               voptgenerror 
2010                 (FLG_ABSTRACT,
2011                  message
2012                  ("Modifies clause in header file accesses abstract "
2013                   "type %s (interface modifies clause should not depend "
2014                   "on or expose type representation): %q",
2015                   ctype_unparse (ct),
2016                   sRef_unparse (s)),
2017                  g_currentloc);
2018             }
2019         }
2020       
2021       cstring_markOwned (f);
2022       return (sRef_makeField (s, f));
2023     }
2024   else
2025     {
2026       voptgenerror 
2027         (FLG_TYPE,
2028          message ("Modifies clause dereferences non-pointer (type %s): %q",
2029                   ctype_unparse (rt),
2030                   sRef_unparse (s)),
2031          g_currentloc);
2032       
2033       cstring_free (f);
2034       return s;
2035     }
2036 }
2037
2038 /*@dependent@*/ sRef clabstract_unrecognizedGlobal (cstring s)
2039 {
2040   if (cstring_equalLit (s, "nothing"))
2041     {
2042       return sRef_makeNothing ();
2043     }
2044   else if (cstring_equalLit (s, "internalState"))
2045     {
2046       return sRef_makeInternalState ();
2047     }
2048   else if (cstring_equalLit (s, "fileSystem")
2049            || cstring_equalLit (s, "systemState"))
2050     {
2051       return sRef_makeSystemState ();
2052     }
2053   else
2054     {
2055       voptgenerror 
2056         (FLG_UNRECOG, 
2057          message ("Unrecognized identifier in globals list: %s", s), 
2058          g_currentloc);
2059       
2060       return sRef_undefined;
2061     }
2062 }
2063
2064 /*@exposed@*/ sRef modListArrowAccess (sRef s, cstring f)
2065 {
2066   ctype ct = sRef_getType (s);
2067   ctype rt = ctype_realType (ct);
2068
2069   if (ctype_isRealPointer (rt))
2070     {
2071       ctype b = ctype_baseArrayPtr (rt);
2072       ctype rb = ctype_realType (b);
2073
2074       if (ctype_isStructorUnion (rb))
2075         {
2076           uentry tf = uentryList_lookupField (ctype_getFields (rb), f);
2077       
2078           if (uentry_isUndefined (tf))
2079             {
2080               voptgenerror (FLG_TYPE,
2081                             message ("Modifies list arrow accesses non-existent "
2082                                      "field %s of %t: %q", f, b, 
2083                                      sRef_unparse (s)),
2084                             g_currentloc);
2085               
2086               cstring_free (f);
2087               return sRef_undefined;
2088             }
2089           else 
2090             {
2091               if (context_inHeader ())
2092                 {
2093                   if (ctype_isAbstract (b))
2094                     {
2095                       voptgenerror 
2096                         (FLG_ABSTRACT,
2097                          message
2098                          ("Modifies clause in header file arrow accesses abstract "
2099                           "type %s (interface modifies clause should not depend "
2100                           "on or expose type representation): %q",
2101                           ctype_unparse (b),
2102                           sRef_unparse (s)),
2103                          g_currentloc);
2104                     }
2105                 }
2106               else 
2107                 {
2108                   if (ctype_isAbstract (rt))
2109                     {
2110                       voptgenerror 
2111                         (FLG_ABSTRACT,
2112                          message
2113                          ("Modifies clause arrow accesses inaccessible abstract "
2114                           "type %s (interface modifies clause should not depend "
2115                           "on or expose type representation): %q",
2116                           ctype_unparse (rt),
2117                           sRef_unparse (s)),
2118                          g_currentloc);
2119                     }
2120                 }
2121             }
2122
2123           cstring_markOwned (f);
2124           return (sRef_makeArrow (s, f));
2125         }
2126       else
2127         {
2128           voptgenerror 
2129             (FLG_TYPE,
2130              message ("Modifies clause arrow accesses pointer to "
2131                       "non-structure (type %s): %q",
2132                       ctype_unparse (rt),
2133                       sRef_unparse (s)),
2134              g_currentloc);
2135         }
2136     }
2137   else
2138     {
2139       voptgenerror 
2140         (FLG_TYPE,
2141          message ("Modifies clause arrow accesses non-pointer (type %s): %q",
2142                   ctype_unparse (rt),
2143                   sRef_unparse (s)),
2144          g_currentloc);
2145     }
2146
2147   cstring_free (f);
2148   return s;
2149 }
2150
2151 sRef checkStateClausesId (uentry ue)
2152 {
2153   cstring s = uentry_rawName (ue);
2154
2155   if (sRef_isFileOrGlobalScope (uentry_getSref (ue)))
2156     {
2157       voptgenerror 
2158         (FLG_COMMENTERROR,
2159          message ("Global variable %s used state clause.  (Global variables "
2160                   "are not recognized in state clauses.  If they are present "
2161                   "they are ignored. "
2162                   " If there is "
2163                   "sufficient interest in support for this, it may be "
2164                   "added to a future release.  Send mail to "
2165                   "info@splint.org.)",
2166                   s),
2167          g_currentloc);
2168       
2169       return sRef_undefined;
2170     }
2171   else
2172     {
2173       if (cstring_equalLit (s, "result"))
2174         {
2175           if (optgenerror 
2176               (FLG_SYNTAX, 
2177                message ("Special clause list uses %s which is a variable and has special "
2178                         "meaning in a modifies list.  (Special meaning assumed.)", s), 
2179                g_currentloc))
2180             {
2181               uentry_showWhereDeclared (ue);
2182             }
2183         }
2184
2185       return uentry_getSref (ue);
2186     }
2187 }
2188 /*drl:1/19/2001
2189   oops to 1/8/2000
2190   date is wronge ..
2191   don;t know what the real date is...
2192   
2193 */
2194
2195 /*drl
2196   added 1/8/2000
2197   based on checkSpecClausesId
2198   called by grammar
2199 */
2200
2201 sRef checkbufferConstraintClausesId (uentry ue)
2202 {
2203   sRef sr;
2204   cstring s = uentry_rawName (ue);
2205
2206   if (cstring_equalLit (s, "result"))
2207     {
2208       if (optgenerror 
2209           (FLG_SYNTAX, 
2210            message ("Function clause list uses %s which is a variable and has special "
2211                     "meaning in a modifies list.  (Special meaning assumed.)", s), 
2212            g_currentloc))
2213         {
2214           uentry_showWhereDeclared (ue);
2215         }
2216     }
2217   
2218   sr = uentry_getSref (ue);
2219
2220   if (sRef_isInvalid (sr))
2221     {
2222       llfatalerrorLoc (cstring_makeLiteral ("Macro defined constants can not be used in function "
2223                                             "constraints unless they are specifed with the constant "
2224                                             "annotation. To use a macro defined constant include an "
2225                                             "annotation of the form /*@constant <type> <name>=<value>@*/ "
2226                                             "somewhere before the function constraint. This restriction "
2227                                             "may be removed in future releases."));
2228     }
2229
2230   /* saveCopy to used to mitigate danger of accessing freed memory*/
2231   return sRef_saveCopy (sr); 
2232 }
2233
2234 void checkModifiesId (uentry ue)
2235 {
2236   cstring s = uentry_rawName (ue);
2237
2238   if (cstring_equalLit (s, "nothing")
2239       || cstring_equalLit (s, "internalState")
2240       || cstring_equalLit (s, "systemState")
2241       || (cstring_equalLit (s, "fileSystem")))
2242     {
2243       if (optgenerror 
2244           (FLG_SYNTAX, 
2245            message ("Modifies list uses %s which is a variable and has special "
2246                     "meaning in a modifies list.  (Special meaning assumed.)", s), 
2247            g_currentloc))
2248         {
2249           uentry_showWhereDeclared (ue);
2250         }
2251     }
2252 }
2253
2254 /*@exposed@*/ sRef fixModifiesId (cstring s) 
2255 {
2256   sRef ret;
2257   cstring pname = makeParam (s);
2258   uentry ue = usymtab_lookupSafe (pname);
2259
2260   cstring_free (pname);
2261
2262   if (cstring_equalLit (s, "nothing"))
2263     {
2264       ret = sRef_makeNothing ();
2265     }
2266   else if (cstring_equalLit (s, "internalState"))
2267     {
2268       ret = sRef_makeInternalState ();
2269     }
2270   else if (cstring_equalLit (s, "fileSystem")
2271            || cstring_equalLit (s, "systemState"))
2272     {
2273       ret = sRef_makeSystemState ();
2274     }
2275   else
2276     {
2277       ret = sRef_undefined;
2278     }
2279
2280   if (sRef_isValid (ret))
2281     {
2282       if (uentry_isValid (ue))
2283         {
2284           voptgenerror 
2285             (FLG_SYNTAX, 
2286              message ("Modifies list uses %s which is a parameter and has special "
2287                       "meaning in a modifies list.  (Special meaning assumed.)", s), 
2288              g_currentloc);
2289         }
2290     }
2291   else
2292     {
2293       if (uentry_isValid (ue))
2294         {
2295           ret = uentry_getSref (ue);
2296         }
2297       else
2298         {
2299           fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s)));
2300           ret = sRef_undefined;
2301
2302           voptgenerror 
2303             (FLG_UNRECOG, 
2304              message ("Unrecognized identifier in modifies comment: %s", s), 
2305              loc);
2306
2307           fileloc_free (loc);
2308         }
2309     }
2310   
2311   return ret;
2312 }
2313
2314 sRef fixStateClausesId (cstring s) 
2315 {
2316   sRef ret;
2317   cstring pname = makeParam (s);
2318   uentry ue = usymtab_lookupSafe (pname);
2319
2320   cstring_free (pname);
2321
2322   if (cstring_equalLit (s, "result"))
2323     {
2324       ret = sRef_makeResult (ctype_unknown);
2325     }
2326   else
2327     {
2328       ret = sRef_undefined;
2329     }
2330
2331   if (sRef_isValid (ret))
2332     {
2333       if (uentry_isValid (ue))
2334         {
2335           voptgenerror 
2336             (FLG_SYNTAX, 
2337              message ("Function clause uses %s which is a parameter and has special "
2338                       "meaning in a function clause.  (Special meaning assumed.)", s), 
2339              g_currentloc);
2340         }
2341     }
2342   else
2343     {
2344       if (uentry_isValid (ue))
2345         {
2346           ret = uentry_getSref (ue);
2347
2348           if (sRef_isFileOrGlobalScope (ret))
2349             {
2350               voptgenerror 
2351                 (FLG_SYNTAX, 
2352                  message ("Global variable %s used in function clause.  (Global variables "
2353                           "are not recognized in function clauses.  If there is "
2354                           "sufficient interest in support for this, it may be "
2355                           "added to a future release.  Send mail to "
2356                           "info@splint.org.)",
2357                           s), 
2358                  g_currentloc);
2359               
2360               ret = sRef_undefined;
2361             }
2362         }
2363       else
2364         {
2365
2366           /* drl This is the code for structure invariants
2367
2368           It is no yet stable enough to be included in a Splint release.
2369           */
2370
2371           /*check that we're in a structure */
2372 #if 0
2373                   /*@unused@*/    uentryList ueL;
2374           /*@unused@*/ uentry ue2;
2375           /*@unused@*/ ctype ct;\r
2376 #endif
2377           fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s)));
2378           ret = sRef_undefined; 
2379 # if 0
2380           
2381           ct = context_getLastStruct ( ct );
2382
2383           llassert( ctype_isStruct(ct) );
2384
2385           ueL =  ctype_getFields (ct);
2386
2387           ue2 = uentryList_lookupField (ueL, s);
2388
2389           if (!uentry_isUndefined(ue2) )
2390             {
2391               ret = uentry_getSref(ue2);
2392               
2393               DPRINTF((
2394                        message("Got field in structure in the annotation constraint: %s (or sref: %s)", s, sRef_unparse(ret) )
2395                        ));
2396               
2397               return ret;
2398             }
2399           
2400 #endif
2401
2402           voptgenerror 
2403             (FLG_UNRECOG, 
2404              message ("Unrecognized identifier in function clause: %s", s), 
2405              loc);
2406
2407           fileloc_free (loc);
2408         }
2409     }
2410   
2411   return ret;
2412 }
2413
2414 sRef modListArrayFetch (/*@exposed@*/ sRef s, /*@unused@*/ sRef mexp)
2415 {
2416   ctype ct = sRef_getType (s);
2417   ctype rt = ctype_realType (ct);
2418
2419   if (ctype_isAP (rt))
2420     {
2421       if (context_inHeader () && ctype_isAbstract (ct))
2422         {
2423           voptgenerror 
2424             (FLG_ABSTRACT,
2425              message
2426              ("Modifies clause in header file indexes abstract "
2427               "type %s (interface modifies clause should not depend "
2428               "on or expose type representation): %q",
2429               ctype_unparse (ct),
2430               sRef_unparse (s)),
2431              g_currentloc);
2432         }
2433       
2434       return (sRef_makeAnyArrayFetch (s));
2435     }
2436   else
2437     {
2438       voptgenerror
2439         (FLG_TYPE,
2440          message
2441          ("Implementation modifies clause uses array fetch on non-array (type %s): %q",
2442           ctype_unparse (ct), sRef_unparse (s)),
2443          g_currentloc);
2444       return s;
2445     }
2446 }
2447
2448 static void clabstract_prepareFunction (uentry e)
2449 {
2450   uentry_checkParams (e);
2451   DPRINTF (("After prepare: %s", uentry_unparseFull (e)));
2452 }
2453
2454 sRef clabstract_checkGlobal (exprNode e)
2455 {
2456   sRef s;
2457   llassert (exprNode_isInitializer (e));
2458
2459   s = exprNode_getSref (e);
2460   DPRINTF (("Initializer: %s -> %s", exprNode_unparse (e), sRef_unparse (s)));
2461
2462   exprNode_free (e);
2463   return sRef_copy (s);
2464 }
This page took 0.254312 seconds and 5 git commands to generate.