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