]> andersk Git - splint.git/blob - src/clabstract.c
d1affb49b70f199a7fb30be7386ca58d7ea53626
[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     constraintList_free(implicitFcnConstraints);
517   
518   implicitFcnConstraints  = constraintList_makeNew();
519   
520   uentryList_elements (params, el)
521     {
522       DPRINTF((message("setImplictfcnConstraints doing: %s", uentry_unparse(el) ) ));
523       
524       if ( uentry_isVariable (el) )
525         {
526           s = uentry_getSref(el);
527           if (sRef_isReference (s) )
528             {
529               
530               DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) ));
531               /*drl 4/26/01
532                 chagned this from MaxSet(s) == 0 to MaxSet(s) >= 0 */
533               c = constraint_makeSRefWriteSafeInt (s, 0);
534               
535               implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
536               
537               /*drl 10/23/2002 added support for out*/
538
539               if (!uentry_isOut(el) )
540                 {
541                   c = constraint_makeSRefReadSafeInt (s, 0);
542                   
543                   implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
544                 }
545             }
546           else
547             {
548               DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) ));
549             }
550         } /*end uentry_isVariable*/
551
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           /*@warning take this out befor@*/
564           llassert(FALSE);
565         }
566     }
567   
568   end_uentryList_elements;
569   DPRINTF((message("implicitFcnConstraints has been set to %s\n",
570                    constraintList_print(implicitFcnConstraints) ) ));
571   
572 }
573
574
575 /*@observer@*/ constraintList  getImplicitFcnConstraints (void)
576 {
577   return implicitFcnConstraints;
578 }
579
580 void setCurrentParams (/*@dependent@*/ uentryList ue)
581 {
582   currentParamList = ue;
583 }
584
585 void clearCurrentParams (void)
586 {
587     currentParamList = uentryList_undefined;
588 }
589
590 /*
591 ** requires: uentry_isFunction (e)
592 **           parameter names for current function are in currentParamList
593 */
594
595 static void enterFunctionParams (uentryList params)
596 {
597   int paramno = 0;
598
599   uentryList_elements (params, current)
600     {
601       if (uentry_hasName (current)) 
602         {
603           uentry_setParamNo (current, paramno);
604           usymtab_supEntry (uentry_copy (current));
605         }
606       
607       paramno++;
608     } end_uentryList_elements; 
609 }
610  
611
612 extern void enterParamsTemp (void)
613 {
614   usymtab_enterScope ();
615   enterFunctionParams (currentParamList);
616 }
617
618 extern void exitParamsTemp (void)
619 {
620   usymtab_quietPlainExitScope ();
621 }
622
623 static /*@exposed@*/ uentry clabstract_globalDeclareFunction (idDecl tid) 
624 {
625   ctype deftype = idDecl_getCtype (tid);
626   ctype rettype;
627   uentry ue;
628   
629   DPRINTF (("Global function: %s", idDecl_unparse (tid)));
630
631   if (ctype_isFunction (deftype))
632     {
633       rettype = ctype_getReturnType (deftype);
634     }
635   else
636     {
637       rettype = ctype_unknown;
638     }
639
640   /*
641   ** check has been moved here...
642   */
643
644   if (ctype_isFunction (idDecl_getCtype (tid)))
645     {
646       ue = uentry_makeIdFunction (tid);
647       reflectSpecialCode (ue);
648       reflectArgsUsed (ue);
649       reflectStorageClass (ue);
650       uentry_checkParams (ue);
651       
652       DPRINTF (("Supercede function: %s", uentry_unparseFull (ue)));
653       
654       ue = usymtab_supGlobalEntryReturn (ue);
655       DPRINTF (("After supercede function: %s", uentry_unparseFull (ue)));
656       
657       DPRINTF (("Enter function: %s", uentry_unparseFull (ue)));
658       context_enterFunction (ue);
659       enterFunctionParams (uentry_getParams (ue));
660       
661       resetStorageClass ();
662       DPRINTF (("Function: %s", uentry_unparseFull (ue)));
663       return (ue);
664     }
665   else
666     {    
667       llparseerror (message ("Non-function declaration: %q",
668                              idDecl_unparse (tid)));
669       return (uentry_undefined);
670     }
671 }
672
673 /*
674 ** for now, no type checking
675 ** (must check later though!)
676 */
677
678 static /*@only@*/ uentry globalDeclareOldStyleFunction (idDecl tid)
679 {
680   uentry ue;
681
682   /*
683   ** check has been moved here...
684   */
685
686   if (cstring_equalLit (idDecl_observeId (tid), "main"))
687     {
688       context_setFlagTemp (FLG_MAINTYPE, FALSE);
689     }
690
691   ue = uentry_makeIdFunction (tid);
692   reflectStorageClass (ue);
693   reflectSpecialCode (ue);
694   reflectArgsUsed (ue);
695   uentry_setDefined (ue, g_currentloc);
696   uentry_checkParams (ue);
697   resetStorageClass ();
698
699   /* context_enterOldStyleScope (); */
700
701   return (ue);
702 }
703
704 static void oldStyleDeclareFunction (/*@only@*/ uentry e)
705 {
706   uentryList params = saveParamList;
707   ctype rt = uentry_getType (e);
708
709   llassert (ctype_isFunction (rt));
710
711   if (uentry_hasStateClauseList (e) 
712       || uentry_hasConditions (e))
713     {
714       llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
715                              fileloc_unparse (g_currentloc), uentry_unparse (e)));
716     }
717
718   e = usymtab_supGlobalEntryReturn (e);
719
720   context_enterFunction (e);
721   enterFunctionParams (params);
722   saveParamList = uentryList_undefined;
723   resetStorageClass ();
724 }
725
726 static void oldStyleCompleteFunction (/*@only@*/ uentry e)
727 {
728   uentryList params = saveParamList;
729   ctype rt = uentry_getType (e);
730
731   llassert (ctype_isFunction (rt));
732
733   if (uentry_hasStateClauseList (e) 
734       || uentry_hasConditions (e))
735     {
736       llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
737                              fileloc_unparse (g_currentloc), uentry_unparse (e)));
738     }
739
740   e = usymtab_supGlobalEntryReturn (e);
741
742   context_completeOldStyleFunction (e);
743   enterFunctionParams (params);
744   saveParamList = uentryList_undefined;
745   resetStorageClass ();
746 }
747
748 void clabstract_declareFunction (idDecl tid) /*@globals undef saveFunction; @*/
749 {
750   uentry ue;
751
752   DPRINTF (("Declare function: %s", idDecl_unparse (tid)));
753   
754   if (ctype_isUnknown (idDecl_getCtype (tid)))
755     {
756       /*
757       ** No type, its really a plain name (int) declaration
758       */
759
760       voptgenerror (FLG_IMPTYPE,
761                     message ("No type before declaration name (implicit int type): %q",
762                              idDecl_unparse (tid)),
763                     g_currentloc);
764       tid = idDecl_replaceCtype (tid, ctype_int);
765       processVariable (tid);
766       saveFunction = uentry_undefined;
767     }
768   else
769     {
770       if (s_processingParams)
771         {
772           ue = globalDeclareOldStyleFunction (tid);
773           saveFunction = ue;
774           DPRINTF (("Set save function: %s", uentry_unparseFull (ue)));
775         }
776       else
777         {
778           saveFunction = uentry_undefined;
779           
780           if (context_inRealFunction ())
781             {
782               ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
783               
784               llparseerror (message ("Function declared inside function: %q",
785                                      idDecl_unparse (tid)));
786               
787               context_quietExitFunction ();
788               ue = usymtab_supEntryReturn (ue);
789             }
790           else
791             {
792               if (context_inInnerScope ())
793                 {
794                   llparseerror (message ("Declaration in inner context: %q",
795                                          idDecl_unparse (tid)));
796                   
797                   sRef_setGlobalScope ();
798                   ue = uentry_makeVariableLoc (idDecl_observeId (tid), 
799                                                ctype_unknown);
800                   ue = usymtab_supGlobalEntryReturn (ue);
801                   sRef_clearGlobalScope ();
802                 }
803               else
804                 {
805                   ue = clabstract_globalDeclareFunction (tid);
806                 }
807             }
808           
809           resetGlobals ();
810         }
811
812       resetStorageClass ();
813     }
814
815   idDecl_free (tid);
816 }
817
818 void declareStaticFunction (idDecl tid) /*@globals undef saveFunction; @*/
819 {
820   uentry ue;
821
822   DPRINTF (("Declare static funciton: %s", idDecl_unparse (tid)));
823
824   if (s_processingParams)
825     {
826       ue = globalDeclareOldStyleFunction (tid);
827       saveFunction = ue;
828     }
829   else
830     {
831       saveFunction = uentry_undefined;
832
833       if (context_inRealFunction ())
834         {
835           ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown);
836
837           llparseerror (message ("Function declared inside function: %q",
838                                  idDecl_unparse (tid)));
839           
840           context_quietExitFunction ();
841           ue = usymtab_supEntryReturn (ue);
842         }
843       else
844         {
845           if (context_inInnerScope ())
846             {
847               llparseerror (message ("Declaration in inner context: %q",
848                                      idDecl_unparse (tid)));
849               
850               sRef_setGlobalScope ();
851               ue = uentry_makeVariableLoc (idDecl_observeId (tid), 
852                                            ctype_unknown);
853               ue = usymtab_supGlobalEntryReturn (ue);
854               sRef_clearGlobalScope ();
855             }
856           else
857             {
858               ctype deftype = idDecl_getCtype (tid);
859               ctype rettype;
860               
861               if (ctype_isFunction (deftype))
862                 {
863                   rettype = ctype_getReturnType (deftype);
864                 }
865               else
866                 {
867                   rettype = ctype_unknown;
868                 }
869               
870               /*
871               ** check has been moved here...
872               */
873               
874               if (ctype_isFunction (idDecl_getCtype (tid)))
875                 {
876                   ue = uentry_makeIdFunction (tid);
877                   reflectSpecialCode (ue);
878                   reflectArgsUsed (ue);
879                 }
880               else
881                 {    
882                   DPRINTF (("Here we are!"));
883                   llparseerror (message ("Inconsistent function declaration: %q",
884                                          idDecl_unparse (tid)));
885                   
886                   tid = idDecl_replaceCtype 
887                     (tid, ctype_makeFunction (ctype_unknown, uentryList_undefined));
888                   ue = uentry_makeIdFunction (tid);
889                 }
890               
891               reflectStorageClass (ue);
892               uentry_setStatic (ue);
893
894               uentry_checkParams (ue);
895         
896               DPRINTF (("Sub global entry: %s", uentry_unparse (ue)));
897               ue = usymtab_supGlobalEntryReturn (ue);
898
899               context_enterFunction (ue);
900               enterFunctionParams (uentry_getParams (ue));
901               resetStorageClass ();
902             }
903         }
904       
905       resetGlobals ();
906     }
907   
908   resetStorageClass ();
909   idDecl_free (tid);
910 }
911
912 void
913 checkTypeDecl (uentry e, ctype rep)
914 {
915   cstring n = uentry_getName (e);
916
917   DPRINTF (("Check type decl: %s", uentry_unparseFull (e)));
918
919   if (cstring_equal (context_getBoolName (), n))
920     {
921       ctype rrep = ctype_realType (rep);
922       
923       /*
924       ** for abstract enum types, we need to fix the enum members:
925       ** they should have the abstract type, not the rep type.
926       */
927       
928       if (ctype_isEnum (ctype_realType (rrep)))
929         {
930           enumNameList el = ctype_elist (rrep);
931           
932           enumNameList_elements (el, ye)
933             {
934               if (usymtab_existsGlob (ye))
935                 {
936                   uentry ue = usymtab_lookupSafe (ye);
937                   uentry_setType (ue, ctype_bool);
938                 }
939
940               if (cstring_equal (context_getTrueName (), ye)
941                   || cstring_equal (context_getFalseName (), ye))
942                 {
943                   ;
944                 }
945               else
946                 {
947                   vgenhinterror 
948                     (FLG_SYNTAX,
949                      message ("Member of boolean enumerated type definition "
950                               "does not match name set to represent true "
951                               "or false: %s",
952                               ye),
953                      message ("Use -boolfalse and -booltrue to set the "
954                               "name of false and true boolean values."),
955                      uentry_whereDefined (e));
956                 }
957             } end_enumNameList_elements;
958         }
959     }
960
961   if (usymtab_exists (n))
962     {
963       usymId llm = usymtab_getId (n);
964       uentry le  = usymtab_getTypeEntry (typeId_fromUsymId (llm));
965
966       uentry_setDeclared (e, g_currentloc); 
967       uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le), stateInfo_currentLoc ()));
968
969       DPRINTF (("Here we are: %s / %s",
970                 n, context_getBoolName ()));
971       
972       if (uentry_isAbstractDatatype (le))
973         {
974           ctype rrep = ctype_realType (rep);
975
976           DPRINTF (("Abstract type: %s", uentry_unparseFull (le)));
977
978           /*
979           ** for abstract enum types, we need to fix the enum members:
980           ** they should have the abstract type, not the rep type.
981           */
982
983           if (ctype_isEnum (ctype_realType (rrep)))
984             {
985               ctype at = uentry_getAbstractType (le);
986               enumNameList el = ctype_elist (rrep);
987
988               enumNameList_elements (el, ye)
989                 {
990                   if (usymtab_existsGlob (ye))
991                     {
992                       uentry ue = usymtab_lookupSafe (ye);
993
994                       llassert (uentry_isEitherConstant (ue));
995
996                       /* evans 2002-04-22 */
997                       if (ctype_isBool (uentry_getType (ue)))
998                         {
999                           /*
1000                           ** If set using -booltrue or -boolfalse, don't change the type.
1001                           */
1002                         }
1003                       else
1004                         {
1005                           llassertprint (ctype_match (uentry_getType (ue), rrep),
1006                                          ("Bad enum: %s / %s",
1007                                           uentry_unparse (ue),
1008                                           ctype_unparse (rrep)));
1009                           
1010                           uentry_setType (ue, at);
1011                         }
1012                     }
1013                 } end_enumNameList_elements;
1014             }
1015           
1016           if (uentry_isMutableDatatype (le))
1017             {
1018               /* maybe more complicated if abstract and immutable ? */
1019
1020               if (!ctype_isRealPointer (rep) && !ctype_isRealAbstract (rep))
1021                 {
1022                   voptgenerror 
1023                     (FLG_MUTREP,
1024                      message ("Mutable abstract type %s declared without pointer "
1025                               "indirection: %s (violates assignment semantics)",
1026                               n, ctype_unparse (rep)),
1027                      uentry_whereDefined (e));
1028                   
1029                   uentry_setMutable (e);
1030                 }
1031             }
1032         }
1033     }
1034   else
1035     {
1036       fileloc fl = uentry_whereDeclared (e);
1037
1038       if (context_getFlag (FLG_LIKELYBOOL)
1039           && !context_getFlag (FLG_BOOLINT))
1040         {
1041           if ((cstring_equalLit (n, "BOOL")
1042                || cstring_equalLit (n, "Bool")
1043                || cstring_equalLit (n, "bool")
1044                || cstring_equalLit (n, "boolean")
1045                || cstring_equalLit (n, "Boolean")
1046                || cstring_equalLit (n, "BOOLEAN"))
1047               && !(cstring_equal (n, context_getBoolName ())))
1048             {
1049               if (context_setBoolName ()) {
1050                 voptgenerror 
1051                   (FLG_LIKELYBOOL,
1052                    message ("Type %s is probably meant as a boolean type, but does "
1053                             "not match the boolean type name \"%s\".",
1054                             n,
1055                             context_getBoolName ()),
1056                    fl);
1057               } else
1058                 voptgenerror 
1059                   (FLG_LIKELYBOOL,
1060                    message ("Type %s is probably meant as a boolean type, "
1061                             "but the boolean type name is not set. "
1062                             "Use -booltype %s to set it.",
1063                             n,
1064                             n),
1065                    fl);
1066                 }
1067         }
1068
1069       if (!uentry_isStatic (e)
1070           && !ctype_isFunction (uentry_getType (e)) 
1071           && !fileloc_isLib (fl) 
1072           && !fileloc_isImport (fl)
1073           && fileloc_isHeader (fl))
1074         {
1075           voptgenerror (FLG_EXPORTTYPE,
1076                         message ("Type exported, but not specified: %s\n", n),
1077                         fl);
1078         }
1079     }
1080
1081   cstring_free (n);
1082 }
1083
1084 uentryList
1085 fixUentryList (idDeclList tl, qtype q)
1086 {
1087   uentryList f = uentryList_new ();
1088   
1089   idDeclList_elements (tl, i)
1090   {
1091     if (idDecl_isDefined (i))
1092       {
1093         uentry ue;
1094         uentry old;
1095         ctype rt;
1096
1097         (void) idDecl_fixBase (i, q);
1098
1099         /*
1100         ** implicit annotations 
1101         */
1102
1103         (void) fixStructDecl (i);
1104
1105         ue = uentry_makeIdVariable (i);
1106         rt = ctype_realType (uentry_getType (ue));
1107
1108         /*
1109         ** where is this here???
1110
1111         if (ctype_isArray (rt) || ctype_isSU (rt))
1112           {
1113             sRef_setAllocated (uentry_getSref (ue), uentry_whereDefined (ue));
1114           }
1115
1116         **
1117         */
1118
1119         if (uentry_isValid (old = uentryList_lookupField (f, uentry_rawName (ue))))
1120           {
1121             if (optgenerror (FLG_SYNTAX,
1122                              message ("Field name reused: %s", uentry_rawName (ue)),
1123                              uentry_whereDefined (ue)))
1124               {
1125                 llgenmsg (message ("Previous use of %s", uentry_rawName (ue)),
1126                           uentry_whereDefined (old));
1127               }
1128           }
1129         
1130         f = uentryList_add (f, ue);
1131       }
1132   } end_idDeclList_elements;
1133
1134   idDeclList_free (tl);
1135   return (f);
1136 }
1137
1138 /*
1139 ** This is a hack to support unnamed struct/union fields as done by
1140 ** Microsoft VC++.  It is not supported by the ANSI standard.  
1141 **
1142 ** The inner fields are added to the outer structure.  This is meaningful
1143 ** for nesting structs inside unions, but Splint does no related 
1144 ** checking.
1145 */
1146
1147 uentryList
1148 fixUnnamedDecl (qtype q)
1149 {
1150   ctype ct = ctype_realType (qtype_getType (q));
1151
1152   if (ctype_isStruct (ct) || ctype_isUnion (ct))
1153     {
1154       return uentryList_single (uentry_makeUnnamedVariable (ct));
1155     }
1156   else if (ctype_isEnum (ct))
1157     {
1158       /* evans 2002-02-05: nothing to do for unnamed enum lists */
1159       return uentryList_undefined;
1160     }
1161   else
1162     { 
1163       voptgenerror 
1164         (FLG_SYNTAX,
1165          message ("Type name in field declarations: %s", qtype_unparse (q)),
1166          g_currentloc);
1167     }
1168
1169   return uentryList_undefined;
1170 }
1171
1172 void setStorageClass (storageClassCode sc)
1173 {
1174   storageClass = sc;
1175 }
1176
1177 void
1178 setProcessingIterVars (uentry iter)
1179 {
1180   s_processingIterVars = TRUE;
1181   currentIter = iter;
1182   saveIterParamNo = 0;
1183 }
1184
1185 void
1186 setProcessingGlobalsList ()
1187 {
1188   s_processingGlobals = TRUE;
1189   fcnNoGlobals = FALSE;
1190 }
1191
1192 static bool ProcessingGlobMods = FALSE;
1193
1194 void
1195 setProcessingGlobMods ()
1196 {
1197   ProcessingGlobMods = TRUE;
1198 }
1199
1200 void
1201 clearProcessingGlobMods ()
1202 {
1203   ProcessingGlobMods = FALSE;
1204 }
1205
1206 bool
1207 isProcessingGlobMods ()
1208 {
1209   return (ProcessingGlobMods);
1210 }
1211
1212 static void resetGlobals (void)
1213 {
1214   s_processingGlobals = FALSE;
1215   fcnNoGlobals = FALSE;
1216 }
1217
1218 void
1219 unsetProcessingGlobals ()
1220 {
1221   s_processingGlobals = FALSE;
1222 }
1223
1224 void
1225 setProcessingVars (/*@only@*/ qtype q)
1226 {
1227   s_processingVars = TRUE;
1228   qtype_free (processingType);
1229   processingType = q;
1230 }
1231
1232 static void
1233 setGenericParamList (/*@dependent@*/ uentryList pm)
1234 {
1235   s_processingParams = TRUE;
1236   saveParamList = pm;
1237 }
1238
1239 void
1240 setProcessingTypedef (qtype q)
1241 {
1242   s_processingTypedef = TRUE;
1243
1244   qtype_free (processingType);
1245   processingType = q;
1246 }
1247
1248 void
1249 unsetProcessingVars ()
1250 {
1251   resetStorageClass ();
1252   s_processingVars = FALSE;
1253 }
1254
1255 void 
1256 oldStyleDoneParams ()
1257 {  
1258   if (s_processingParams)
1259     {
1260       if (uentry_isInvalid (saveFunction))
1261         {
1262           llbuglit ("unsetProcessingVars: no saved function\n");
1263         }
1264       else
1265         {
1266           ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
1267           uentryList params = uentryList_copy (saveParamList);
1268           ctype ct2 = ctype_makeFunction (ct, params);
1269
1270           uentry_setType (saveFunction, ct2);
1271           s_processingParams = FALSE;
1272
1273           oldStyleCompleteFunction (saveFunction);
1274           saveFunction = uentry_undefined;
1275           resetGlobals ();
1276         }
1277     }
1278   else
1279     {
1280       /*
1281       ** If the paramlist used a type name, we could be here.
1282       */
1283
1284       llfatalerror (message ("%q: Old-style function parameter list uses a "
1285                              "type name.", fileloc_unparse (g_currentloc)));
1286     }
1287 }
1288
1289 void 
1290 checkDoneParams ()
1291 {
1292   if (uentry_isValid (saveFunction))
1293     {
1294       /*
1295       ** old style declaration
1296       */
1297
1298       ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
1299       ctype ct2;
1300
1301       DPRINTF (("save function: %s", uentry_unparseFull (saveFunction)));
1302
1303       uentryList_elements (saveParamList, current)
1304         {
1305           uentry_setType (current, ctype_int); /* all params are ints */
1306         } end_uentryList_elements; 
1307
1308       ct2 = ctype_makeParamsFunction (ct, uentryList_copy (saveParamList));
1309       
1310       uentry_setType (saveFunction, ct2);
1311       s_processingParams = FALSE;
1312       
1313       oldStyleDeclareFunction (saveFunction);
1314       saveFunction = uentry_undefined;
1315     }
1316 }
1317
1318 void clabstract_declareType (/*@only@*/ exprNodeList decls, /*@only@*/ warnClause warn)
1319 {
1320   llassert (s_processingTypedef);
1321
1322   DPRINTF (("Declare type: %s", exprNodeList_unparse (decls)));
1323
1324   if (warnClause_isDefined (warn))
1325     {
1326       DPRINTF (("Has a warn clause!"));
1327       DPRINTF (("Warn: %s", warnClause_unparse (warn)));
1328
1329       exprNodeList_elements (decls, el)
1330         {
1331           uentry ue = exprNode_getUentry (el);
1332           cstring uname = uentry_getName (ue);
1333
1334           DPRINTF (("Entry: %s", exprNode_unparse (el)));
1335
1336           /*
1337           ** Need to lookup again to make sure we have the right one...
1338           */
1339
1340           ue = usymtab_lookupExposeGlob (uname);
1341
1342           llassert (uentry_isValid (ue));
1343           llassert (uentry_isDatatype (ue));
1344
1345           DPRINTF (("Warning for %s: %s",
1346                     uentry_unparse (ue), warnClause_unparse (warn)));
1347
1348           uentry_addWarning (ue, warnClause_copy (warn));
1349           DPRINTF (("After add warning: %s", uentry_unparseFull (ue)));
1350           cstring_free (uname);
1351         } end_exprNodeList_elements;
1352     }
1353
1354   warnClause_free (warn);
1355   exprNodeList_free (decls);
1356   unsetProcessingTypedef ();
1357 }
1358
1359 void
1360 unsetProcessingTypedef ()
1361 {
1362   s_processingTypedef = FALSE;
1363 }
1364
1365 void checkConstant (qtype t, idDecl id) 
1366 {
1367   uentry e;
1368   
1369   id = idDecl_fixBase (id, t);
1370   e = uentry_makeIdConstant (id);
1371   
1372   reflectStorageClass (e);
1373   resetStorageClass ();
1374
1375   DPRINTF (("Constant: %s", uentry_unparseFull (e)));
1376   usymtab_supGlobalEntry (e);
1377 }
1378
1379 void checkValueConstant (qtype t, idDecl id, exprNode e) 
1380 {
1381   uentry ue;
1382
1383   id = idDecl_fixBase (id, t);
1384   ue = uentry_makeIdConstant (id);
1385   reflectStorageClass (ue);
1386   resetStorageClass ();
1387
1388   if (exprNode_isDefined (e))
1389     {
1390       if (!exprNode_matchType (uentry_getType (ue), e))
1391         {
1392           (void) gentypeerror 
1393             (exprNode_getType (e), e,
1394              uentry_getType (ue), exprNode_undefined,
1395              message ("Constant %q initialized to type %t, expects %t: %s",
1396                       uentry_getName (ue),  
1397                       exprNode_getType (e), 
1398                       uentry_getType (ue),
1399                       exprNode_unparse (e)),
1400              exprNode_loc (e));
1401         }
1402       else
1403         {
1404           if (exprNode_hasValue (e))
1405             {
1406               uentry_mergeConstantValue (ue, multiVal_copy (exprNode_getValue (e)));
1407             }
1408           else
1409             {
1410               DPRINTF (("No value: %s", exprNode_unparse (e)));
1411             }
1412         }
1413     }
1414
1415   DPRINTF (("Constant value: %s", uentry_unparseFull (ue)));
1416   usymtab_supGlobalEntry (ue);
1417 }
1418
1419 static void processVariable (idDecl t)
1420 {
1421   uentry e;
1422   ctype ct;
1423   
1424   ct = ctype_realType (idDecl_getCtype (t));
1425   
1426   if (s_processingParams)
1427     {
1428       cstring id = idDecl_getName (t);
1429       int paramno = uentryList_lookupRealName (saveParamList, id);
1430       
1431       if (paramno >= 0)
1432         {
1433           uentry cparam = uentryList_getN (saveParamList, paramno);
1434           
1435           DPRINTF (("Processing param: %s", uentry_unparseFull (cparam)));
1436           uentry_setType (cparam, idDecl_getCtype (t));
1437           uentry_reflectQualifiers (cparam, idDecl_getQuals (t));
1438           uentry_setDeclaredOnly (cparam, context_getSaveLocation ());
1439           DPRINTF (("Processing param: %s", uentry_unparseFull (cparam)));
1440         }
1441       else
1442         {
1443           llfatalerrorLoc
1444             (message ("Old style declaration uses unlisted parameter: %s", 
1445                       id));
1446         }
1447     }
1448   else
1449     {
1450       fileloc loc;
1451       
1452       if (context_inIterDef ())
1453         {
1454           cstring pname = makeParam (idDecl_observeId (t));
1455           uentry p = usymtab_lookupSafe (pname);
1456           
1457           cstring_free (pname);
1458           
1459           if (uentry_isYield (p))
1460             {
1461               e = uentry_makeParam (t, sRef_getParam (uentry_getSref (p)));
1462               uentry_checkYieldParam (p, e);
1463               usymtab_supEntrySref (e);
1464               return;
1465             }
1466         }
1467       
1468       if ((hasSpecialCode () || argsUsed)
1469           && ctype_isFunction (idDecl_getCtype (t)))
1470         {
1471           e = uentry_makeIdFunction (t);
1472           reflectSpecialCode (e);
1473           reflectArgsUsed (e);
1474         }
1475       else
1476         {
1477           e = uentry_makeIdVariable (t);
1478         }
1479       
1480       loc = uentry_whereDeclared (e);
1481       
1482       /*
1483         if (context_inGlobalScope ())
1484         {
1485         uentry_checkParams was here!
1486         }
1487       */
1488       
1489       if (ctype_isFunction (uentry_getType (e)))
1490         {
1491           clabstract_prepareFunction (e);
1492         }
1493       
1494       DPRINTF (("Superceding... %s", uentry_unparseFull (e)));
1495       e = usymtab_supEntrySrefReturn (e);
1496       DPRINTF (("After superceding... %s", uentry_unparseFull (e)));      
1497       
1498       if (uentry_isExtern (e) && !context_inGlobalScope ())
1499         {
1500           voptgenerror 
1501             (FLG_NESTEDEXTERN,
1502              message ("Declaration using extern inside function scope: %q",
1503                       uentry_unparse (e)),
1504              g_currentloc);
1505           
1506           uentry_setDefined (e, fileloc_getExternal ());
1507           sRef_setDefined (uentry_getSref (e), fileloc_getExternal ());
1508         }
1509       
1510       if (uentry_isFunction (e))
1511         {
1512           if (!context_inXHFile ())
1513             {
1514               checkParamNames (e);
1515             }
1516         }
1517       
1518       if (uentry_isVar (e) && uentry_isCheckedUnknown (e))
1519         {
1520           sRef sr = uentry_getSref (e);
1521           
1522           if (sRef_isLocalVar (sr))
1523             {
1524               if (context_getFlag (FLG_IMPCHECKMODINTERNALS))
1525                 {
1526                   uentry_setCheckMod (e);
1527                 }
1528               else
1529                 {
1530                   uentry_setUnchecked (e);
1531                 }
1532             }
1533           else if (sRef_isFileStatic (sr))
1534             {
1535               if (context_getFlag (FLG_IMPCHECKEDSTRICTSTATICS))
1536                 {
1537                   uentry_setCheckedStrict (e);
1538                 }
1539               else if (context_getFlag (FLG_IMPCHECKEDSTATICS))
1540                 {
1541                   uentry_setChecked (e);
1542                 }
1543               else if (context_getFlag (FLG_IMPCHECKMODSTATICS))
1544                 {
1545                   uentry_setCheckMod (e);
1546                 }
1547               else
1548                 {
1549                   ;
1550                 }
1551             }
1552           else /* real global */
1553             {
1554               llassert (sRef_isRealGlobal (sr));
1555               
1556               if (context_getFlag (FLG_IMPCHECKEDSTRICTGLOBALS))
1557                 {
1558                   uentry_setCheckedStrict (e);
1559                 }
1560               else if (context_getFlag (FLG_IMPCHECKEDGLOBALS))
1561                 {
1562                   uentry_setChecked (e);
1563                 }
1564               else if (context_getFlag (FLG_IMPCHECKMODGLOBALS))
1565                 {
1566                   uentry_setCheckMod (e);
1567                 }
1568               else
1569                 {
1570                   ;
1571                 }
1572             }
1573         }
1574     }
1575 }
1576
1577 void processNamedDecl (idDecl t)
1578 {
1579   if (qtype_isUndefined (processingType))
1580     {
1581       processingType = qtype_create (ctype_int);
1582       t = idDecl_fixBase (t, processingType);
1583
1584       voptgenerror (FLG_IMPTYPE,
1585                     message ("No type before declaration name (implicit int type): %q",
1586                              idDecl_unparse (t)),
1587                     g_currentloc);
1588     }
1589   else
1590     {
1591       t = idDecl_fixBase (t, processingType);
1592     }
1593
1594   DPRINTF (("Declare: %s", idDecl_unparse (t)));
1595   
1596   if (s_processingGlobals)
1597     {
1598       cstring id = idDecl_getName (t);
1599       uentry ue = usymtab_lookupSafe (id);
1600       
1601       if (!uentry_isValid (ue))
1602         {
1603           llerror (FLG_UNRECOG,
1604                    message ("Variable used in globals list is undeclared: %s", id));
1605         }
1606       else
1607         {
1608           if (!ctype_match (uentry_getType (ue), idDecl_getCtype (t)))
1609             {
1610               voptgenerror 
1611                 (FLG_INCONDEFS,
1612                  message ("Variable %s used in globals list declared %s, "
1613                           "but listed as %s", 
1614                           id, ctype_unparse (uentry_getType (ue)), 
1615                           ctype_unparse (idDecl_getCtype (t))),
1616                  g_currentloc);
1617             }
1618           else
1619             {
1620               sRef sr = sRef_copy (uentry_getSref (ue));
1621               reflectGlobalQualifiers (sr, idDecl_getQuals (t));
1622             }
1623         }
1624     }
1625   else if (s_processingVars)
1626     {
1627       processVariable (t);
1628     }
1629   else if (s_processingTypedef)
1630     {
1631       ctype ct = idDecl_getCtype (t);
1632       uentry e;
1633       
1634       DPRINTF (("Processing typedef: %s", ctype_unparse (ct)));
1635       
1636       e = uentry_makeIdDatatype (t);
1637
1638       if (cstring_equal (idDecl_getName (t), context_getBoolName ())) {
1639         ctype rt = ctype_realType (ct);
1640         
1641         if (ctype_isEnum (rt)) {
1642           ;
1643         } else {
1644           if (!(ctype_isInt (rt)
1645                 || ctype_isUnknown (rt)
1646                 || ctype_isChar (rt))) {
1647             (void) llgenerror
1648               (FLG_BOOLTYPE, 
1649                message ("Boolean type %s defined using non-standard type %s (integral, char or enum type expected)",
1650                         context_getBoolName (),
1651                         ctype_unparse (ct)),
1652                uentry_whereLast (e));
1653           }
1654           
1655           ct = ctype_bool;
1656           uentry_setType (e, ct);
1657         }
1658       }
1659
1660       reflectStorageClass (e);
1661       checkTypeDecl (e, ct);
1662       
1663       e = usymtab_supReturnTypeEntry (e);
1664     }
1665   else
1666     {
1667       llparseerror (message ("Suspect missing struct or union keyword: %q",
1668                              idDecl_unparse (t)));
1669     }
1670
1671   }
1672
1673 /*
1674 ** moved from grammar
1675 */
1676
1677 static idDecl fixStructDecl (/*@returned@*/ idDecl d)
1678 {
1679   if (ctype_isVisiblySharable (idDecl_getCtype (d)) 
1680       && context_getFlag (FLG_STRUCTIMPONLY))
1681     {
1682       if (!qualList_hasAliasQualifier (idDecl_getQuals (d)))
1683         {
1684           if (qualList_hasExposureQualifier (idDecl_getQuals (d)))
1685             {
1686               idDecl_addQual (d, qual_createDependent ());
1687             }
1688           else
1689             {
1690               idDecl_addQual (d, qual_createImpOnly ());
1691             }
1692         }
1693     }
1694
1695   return d;
1696 }
1697
1698 ctype
1699 declareUnnamedStruct (/*@only@*/ uentryList f)
1700 {
1701   DPRINTF (("Unnamed struct: %s", uentryList_unparse (f)));
1702
1703   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1704     {
1705       int num = uentryList_size (f);
1706       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1707
1708       if (num > max)
1709         {
1710           voptgenerror 
1711             (FLG_NUMSTRUCTFIELDS,
1712              message ("Structure declared with %d fields "
1713                       "(limit is set to %d)",
1714                       num, max),
1715              g_currentloc);
1716         }
1717     }
1718
1719   return (ctype_createUnnamedStruct (f));
1720 }
1721
1722 ctype
1723 declareUnnamedUnion (/*@only@*/ uentryList f)
1724 {
1725   DPRINTF (("Unnamed union: %s", uentryList_unparse (f)));
1726
1727   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1728     {
1729       int num = uentryList_size (f);
1730       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1731
1732       if (num > max)
1733         {
1734           voptgenerror 
1735             (FLG_NUMSTRUCTFIELDS,
1736              message ("Union declared with %d fields "
1737                       "(limit is set to %d)",
1738                       num, max),
1739              g_currentloc);
1740         }
1741     }
1742
1743   return (ctype_createUnnamedUnion (f));
1744 }
1745
1746 ctype declareStruct (cstring id, /*@only@*/ uentryList f)
1747 {
1748   ctype ct; 
1749   uentry ue;
1750   int num = uentryList_size (f);
1751
1752   DPRINTF (("Declare struct: %s / %s [%d]", id, uentryList_unparse (f),
1753             uentryList_size (f)));
1754
1755   ct = ctype_createStruct (cstring_copy (id), f);
1756
1757   DPRINTF (("Ctype: %s", ctype_unparse (ct)));
1758
1759   ue = uentry_makeStructTagLoc (id, ct);
1760
1761   DPRINTF (("ue: %s", uentry_unparseFull (ue)));
1762
1763   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1764     {
1765       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1766
1767       if (num > max)
1768         {
1769           voptgenerror 
1770             (FLG_NUMSTRUCTFIELDS,
1771              message ("Structure %q declared with %d fields "
1772                       "(limit is set to %d)",
1773                       uentry_getName (ue), num, max),
1774              uentry_whereLast (ue));
1775         }
1776     }
1777
1778   return (usymtab_supTypeEntry (ue));
1779 }
1780
1781 ctype declareUnion (cstring id, uentryList f)
1782 {
1783   ctype ct; 
1784   uentry ue;
1785   int num = uentryList_size (f);
1786
1787   ct = ctype_createUnion (cstring_copy (id), f);
1788   ue = uentry_makeUnionTagLoc (id, ct);
1789
1790   if (context_maybeSet (FLG_NUMSTRUCTFIELDS))
1791     {
1792       int max = context_getValue (FLG_NUMSTRUCTFIELDS);
1793
1794       if (num > max)
1795         {
1796           voptgenerror 
1797             (FLG_NUMSTRUCTFIELDS,
1798              message ("Union %q declared with %d fields "
1799                       "(limit is set to %d)",
1800                       uentry_getName (ue), num, max),
1801              uentry_whereLast (ue));
1802         }
1803     }
1804
1805   return (usymtab_supTypeEntry (ue));
1806 }
1807
1808 ctype handleStruct (/*@only@*/ cstring id)
1809 {
1810   if (usymtab_existsStructTag (id))
1811     {
1812       ctype ct = uentry_getAbstractType (usymtab_lookupStructTag (id));
1813
1814       cstring_free (id);
1815       return ct;
1816     }
1817   else
1818     {
1819       return (ctype_createForwardStruct (id));
1820     }
1821 }
1822
1823 ctype handleUnion (/*@only@*/ cstring id)
1824 {
1825   if (usymtab_existsUnionTag (id))
1826     {
1827       ctype ret = uentry_getAbstractType (usymtab_lookupUnionTag (id));
1828       cstring_free (id);
1829       return (ret);
1830     }
1831   else
1832     {
1833       return (ctype_createForwardUnion (id));
1834     }
1835 }
1836
1837 ctype
1838 handleEnum (cstring id)
1839 {
1840   if (usymtab_existsEnumTag (id))
1841     {
1842       ctype ret = uentry_getAbstractType (usymtab_lookupEnumTag (id));
1843       cstring_free (id);
1844       return ret;
1845     }
1846   else
1847     {
1848       return (ctype_createForwardEnum (id));
1849     }
1850 }
1851
1852 bool processingIterVars (void) 
1853
1854   return s_processingIterVars; 
1855 }
1856
1857 uentry getCurrentIter (void) 
1858 {
1859   return currentIter; 
1860 }
1861
1862 static bool flipOldStyle = FALSE;
1863 static bool flipNewStyle = TRUE;
1864
1865 void setFlipOldStyle ()          { flipOldStyle = TRUE; }
1866 bool isFlipOldStyle ()           { return flipOldStyle; }
1867 bool isNewStyle ()               { return flipNewStyle; }
1868 void setNewStyle ()              { flipNewStyle = TRUE; }
1869
1870 /*@dependent@*/ uentryList handleParamIdList (/*@dependent@*/ uentryList params)
1871 {  
1872   int paramno = 0;
1873
1874   /*
1875   ** this is a really YUCKY hack to handle old style
1876   ** declarations.
1877   */
1878   
1879   voptgenerror (FLG_OLDSTYLE,
1880                 cstring_makeLiteral ("Old style function declaration"),
1881                 g_currentloc); 
1882
1883   DPRINTF (("Handle old style params: %s", uentryList_unparseFull (params)));
1884
1885   uentryList_elements (params, current)
1886     {
1887       uentry_setParam (current);
1888       uentry_setSref (current, sRef_makeParam 
1889                       (paramno, ctype_unknown, 
1890                        stateInfo_makeLoc (uentry_whereLast (current), SA_DECLARED)));
1891       paramno++;
1892     } end_uentryList_elements;
1893
1894   setGenericParamList (params);
1895   cscannerHelp_setExpectingTypeName ();
1896
1897   return params;
1898 }
1899
1900 /*@dependent@*/ uentryList handleParamTypeList (/*@returned@*/ uentryList params)
1901 {
1902   if (flipOldStyle)
1903     {
1904       uentryList_fixMissingNames (params);
1905
1906       voptgenerror (FLG_OLDSTYLE, 
1907                     cstring_makeLiteral ("Old style function declaration."), 
1908                     g_currentloc); 
1909       
1910       setGenericParamList (params);
1911       flipOldStyle = FALSE;
1912       cscannerHelp_setExpectingTypeName ();
1913     }
1914  
1915   return (params); 
1916 }
1917
1918 void
1919 doVaDcl ()
1920 {
1921   ctype c = ctype_unknown;
1922   cstring id = cstring_makeLiteral ("va_alist");
1923   uentry e;
1924
1925   if (s_processingParams)
1926     {
1927       int i = uentryList_lookupRealName (saveParamList, id);
1928       
1929       if (i >= 0)
1930         {
1931           fileloc loc = context_getSaveLocation ();
1932           e = uentry_makeVariableSrefParam 
1933             (id, c, loc, 
1934              sRef_makeParam (i, c, stateInfo_makeLoc (loc, SA_DECLARED)));
1935         }
1936       else
1937         {
1938           e = uentry_undefined; /* suppress gcc message */
1939           llfatalerrorLoc (cstring_makeLiteral ("va_dcl used without va_alist"));
1940         }
1941     }
1942   else
1943     {    
1944       llerror (FLG_SYNTAX, cstring_makeLiteral ("va_dcl used outside of function declaration"));
1945       e = uentry_makeVariableLoc (id, c);
1946     }
1947
1948   cstring_free (id);
1949   uentry_setUsed (e, g_currentloc);  
1950   usymtab_supEntrySref (e);
1951 }
1952
1953 /*@exposed@*/ sRef modListPointer (/*@exposed@*/ sRef s)
1954 {
1955   ctype ct = sRef_getType (s);
1956   ctype rt = ctype_realType (ct);
1957   
1958   if (ctype_isAP (rt))
1959     {
1960       if (context_inHeader () && ctype_isAbstract (ct))
1961         {
1962           voptgenerror 
1963             (FLG_ABSTRACT,
1964              message
1965              ("Modifies clause in header file dereferences abstract "
1966               "type %s (interface modifies clause should not depend "
1967               "on or expose type representation): %q",
1968               ctype_unparse (ct),
1969               sRef_unparse (s)),
1970              g_currentloc);
1971         }
1972
1973       return (sRef_constructPointer (s));
1974     }
1975   else
1976     {
1977       if (ctype_isKnown (rt))
1978         {
1979           voptgenerror 
1980             (FLG_TYPE,
1981              message ("Implementation modifies clause dereferences non-pointer (type %s): %q",
1982                       ctype_unparse (rt),
1983                       sRef_unparse (s)),
1984              g_currentloc);
1985         }
1986
1987       return s;
1988     }
1989 }
1990
1991 /*@exposed@*/ sRef modListFieldAccess (sRef s, cstring f)
1992 {
1993   ctype ct = sRef_getType (s);
1994   ctype rt = ctype_realType (ct);
1995   
1996   if (ctype_isStructorUnion (rt))
1997     {
1998       uentry tf = uentryList_lookupField (ctype_getFields (rt), f);
1999       
2000       if (uentry_isUndefined (tf))
2001         {
2002           voptgenerror (FLG_TYPE,
2003                         message ("Modifies list accesses non-existent "
2004                                  "field %s of %t: %q", f, ct, 
2005                                  sRef_unparse (s)),
2006                         g_currentloc);
2007           
2008           cstring_free (f);
2009           return sRef_undefined;
2010         }
2011       else 
2012         {
2013           if (ctype_isAbstract (ct) && context_inHeader ())
2014             {
2015               voptgenerror 
2016                 (FLG_ABSTRACT,
2017                  message
2018                  ("Modifies clause in header file accesses abstract "
2019                   "type %s (interface modifies clause should not depend "
2020                   "on or expose type representation): %q",
2021                   ctype_unparse (ct),
2022                   sRef_unparse (s)),
2023                  g_currentloc);
2024             }
2025         }
2026       
2027       cstring_markOwned (f);
2028       return (sRef_makeField (s, f));
2029     }
2030   else
2031     {
2032       voptgenerror 
2033         (FLG_TYPE,
2034          message ("Modifies clause dereferences non-pointer (type %s): %q",
2035                   ctype_unparse (rt),
2036                   sRef_unparse (s)),
2037          g_currentloc);
2038       
2039       cstring_free (f);
2040       return s;
2041     }
2042 }
2043
2044 /*@dependent@*/ sRef clabstract_unrecognizedGlobal (cstring s)
2045 {
2046   if (cstring_equalLit (s, "nothing"))
2047     {
2048       return sRef_makeNothing ();
2049     }
2050   else if (cstring_equalLit (s, "internalState"))
2051     {
2052       return sRef_makeInternalState ();
2053     }
2054   else if (cstring_equalLit (s, "fileSystem")
2055            || cstring_equalLit (s, "systemState"))
2056     {
2057       return sRef_makeSystemState ();
2058     }
2059   else
2060     {
2061       voptgenerror 
2062         (FLG_UNRECOG, 
2063          message ("Unrecognized identifier in globals list: %s", s), 
2064          g_currentloc);
2065       
2066       return sRef_undefined;
2067     }
2068 }
2069
2070 /*@exposed@*/ sRef modListArrowAccess (sRef s, cstring f)
2071 {
2072   ctype ct = sRef_getType (s);
2073   ctype rt = ctype_realType (ct);
2074
2075   if (ctype_isRealPointer (rt))
2076     {
2077       ctype b = ctype_baseArrayPtr (rt);
2078       ctype rb = ctype_realType (b);
2079
2080       if (ctype_isStructorUnion (rb))
2081         {
2082           uentry tf = uentryList_lookupField (ctype_getFields (rb), f);
2083       
2084           if (uentry_isUndefined (tf))
2085             {
2086               voptgenerror (FLG_TYPE,
2087                             message ("Modifies list arrow accesses non-existent "
2088                                      "field %s of %t: %q", f, b, 
2089                                      sRef_unparse (s)),
2090                             g_currentloc);
2091               
2092               cstring_free (f);
2093               return sRef_undefined;
2094             }
2095           else 
2096             {
2097               if (context_inHeader ())
2098                 {
2099                   if (ctype_isAbstract (b))
2100                     {
2101                       voptgenerror 
2102                         (FLG_ABSTRACT,
2103                          message
2104                          ("Modifies clause in header file arrow accesses abstract "
2105                           "type %s (interface modifies clause should not depend "
2106                           "on or expose type representation): %q",
2107                           ctype_unparse (b),
2108                           sRef_unparse (s)),
2109                          g_currentloc);
2110                     }
2111                 }
2112               else 
2113                 {
2114                   if (ctype_isAbstract (rt))
2115                     {
2116                       voptgenerror 
2117                         (FLG_ABSTRACT,
2118                          message
2119                          ("Modifies clause arrow accesses inaccessible abstract "
2120                           "type %s (interface modifies clause should not depend "
2121                           "on or expose type representation): %q",
2122                           ctype_unparse (rt),
2123                           sRef_unparse (s)),
2124                          g_currentloc);
2125                     }
2126                 }
2127             }
2128
2129           cstring_markOwned (f);
2130           return (sRef_makeArrow (s, f));
2131         }
2132       else
2133         {
2134           voptgenerror 
2135             (FLG_TYPE,
2136              message ("Modifies clause arrow accesses pointer to "
2137                       "non-structure (type %s): %q",
2138                       ctype_unparse (rt),
2139                       sRef_unparse (s)),
2140              g_currentloc);
2141         }
2142     }
2143   else
2144     {
2145       voptgenerror 
2146         (FLG_TYPE,
2147          message ("Modifies clause arrow accesses non-pointer (type %s): %q",
2148                   ctype_unparse (rt),
2149                   sRef_unparse (s)),
2150          g_currentloc);
2151     }
2152
2153   cstring_free (f);
2154   return s;
2155 }
2156
2157 sRef checkStateClausesId (uentry ue)
2158 {
2159   cstring s = uentry_rawName (ue);
2160
2161   if (sRef_isFileOrGlobalScope (uentry_getSref (ue)))
2162     {
2163       voptgenerror 
2164         (FLG_COMMENTERROR,
2165          message ("Global variable %s used state clause.  (Global variables "
2166                   "are not recognized in state clauses.  If they are present "
2167                   "they are ignored. "
2168                   " If there is "
2169                   "sufficient interest in support for this, it may be "
2170                   "added to a future release.  Send mail to "
2171                   "info@splint.org.)",
2172                   s),
2173          g_currentloc);
2174       
2175       return sRef_undefined;
2176     }
2177   else
2178     {
2179       if (cstring_equalLit (s, "result"))
2180         {
2181           if (optgenerror 
2182               (FLG_SYNTAX, 
2183                message ("Special clause list uses %s which is a variable and has special "
2184                         "meaning in a modifies list.  (Special meaning assumed.)", s), 
2185                g_currentloc))
2186             {
2187               uentry_showWhereDeclared (ue);
2188             }
2189         }
2190
2191       return uentry_getSref (ue);
2192     }
2193 }
2194 /*drl:1/19/2001
2195   oops to 1/8/2000
2196   date is wronge ..
2197   don;t know what the real date is...
2198   
2199 */
2200
2201 /*drl
2202   added 1/8/2000
2203   based on checkSpecClausesId
2204   called by grammar
2205 */
2206
2207 sRef checkbufferConstraintClausesId (uentry ue)
2208 {
2209   sRef sr;
2210   cstring s = uentry_rawName (ue);
2211
2212   if (cstring_equalLit (s, "result"))
2213     {
2214       if (optgenerror 
2215           (FLG_SYNTAX, 
2216            message ("Function clause list uses %s which is a variable and has special "
2217                     "meaning in a modifies list.  (Special meaning assumed.)", s), 
2218            g_currentloc))
2219         {
2220           uentry_showWhereDeclared (ue);
2221         }
2222     }
2223   
2224   DPRINTF (("constraint id: %s", uentry_unparseFull (ue)));
2225   sr = uentry_getSref (ue);
2226
2227   if (sRef_isInvalid (sr) )
2228     {
2229       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." ));
2230     }
2231
2232   /*@ savedCopy to used to mitigate danger of accessing freed memory*/
2233   return sRef_saveCopy (sr); 
2234 }
2235
2236 void checkModifiesId (uentry ue)
2237 {
2238   cstring s = uentry_rawName (ue);
2239
2240   if (cstring_equalLit (s, "nothing")
2241       || cstring_equalLit (s, "internalState")
2242       || cstring_equalLit (s, "systemState")
2243       || (cstring_equalLit (s, "fileSystem")))
2244     {
2245       if (optgenerror 
2246           (FLG_SYNTAX, 
2247            message ("Modifies list uses %s which is a variable and has special "
2248                     "meaning in a modifies list.  (Special meaning assumed.)", s), 
2249            g_currentloc))
2250         {
2251           uentry_showWhereDeclared (ue);
2252         }
2253     }
2254 }
2255
2256 /*@exposed@*/ sRef fixModifiesId (cstring s) 
2257 {
2258   sRef ret;
2259   cstring pname = makeParam (s);
2260   uentry ue = usymtab_lookupSafe (pname);
2261
2262   cstring_free (pname);
2263
2264   if (cstring_equalLit (s, "nothing"))
2265     {
2266       ret = sRef_makeNothing ();
2267     }
2268   else if (cstring_equalLit (s, "internalState"))
2269     {
2270       ret = sRef_makeInternalState ();
2271     }
2272   else if (cstring_equalLit (s, "fileSystem")
2273            || cstring_equalLit (s, "systemState"))
2274     {
2275       ret = sRef_makeSystemState ();
2276     }
2277   else
2278     {
2279       ret = sRef_undefined;
2280     }
2281
2282   if (sRef_isValid (ret))
2283     {
2284       if (uentry_isValid (ue))
2285         {
2286           voptgenerror 
2287             (FLG_SYNTAX, 
2288              message ("Modifies list uses %s which is a parameter and has special "
2289                       "meaning in a modifies list.  (Special meaning assumed.)", s), 
2290              g_currentloc);
2291         }
2292     }
2293   else
2294     {
2295       if (uentry_isValid (ue))
2296         {
2297           ret = uentry_getSref (ue);
2298         }
2299       else
2300         {
2301           fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s)));
2302           ret = sRef_undefined;
2303
2304           voptgenerror 
2305             (FLG_UNRECOG, 
2306              message ("Unrecognized identifier in modifies comment: %s", s), 
2307              loc);
2308
2309           fileloc_free (loc);
2310         }
2311     }
2312   
2313   return ret;
2314 }
2315
2316 sRef fixStateClausesId (cstring s) 
2317 {
2318   sRef ret;
2319   cstring pname = makeParam (s);
2320   uentry ue = usymtab_lookupSafe (pname);
2321
2322   cstring_free (pname);
2323
2324   if (cstring_equalLit (s, "result"))
2325     {
2326       ret = sRef_makeResult (ctype_unknown);
2327     }
2328   else
2329     {
2330       ret = sRef_undefined;
2331     }
2332
2333   if (sRef_isValid (ret))
2334     {
2335       if (uentry_isValid (ue))
2336         {
2337           voptgenerror 
2338             (FLG_SYNTAX, 
2339              message ("Function clause uses %s which is a parameter and has special "
2340                       "meaning in a function clause.  (Special meaning assumed.)", s), 
2341              g_currentloc);
2342         }
2343     }
2344   else
2345     {
2346       if (uentry_isValid (ue))
2347         {
2348           ret = uentry_getSref (ue);
2349
2350           if (sRef_isFileOrGlobalScope (ret))
2351             {
2352               voptgenerror 
2353                 (FLG_SYNTAX, 
2354                  message ("Global variable %s used in function clause.  (Global variables "
2355                           "are not recognized in function clauses.  If there is "
2356                           "sufficient interest in support for this, it may be "
2357                           "added to a future release.  Send mail to "
2358                           "info@splint.org.)",
2359                           s), 
2360                  g_currentloc);
2361               
2362               ret = sRef_undefined;
2363             }
2364         }
2365       else
2366         {
2367
2368           /* drl This is the code for structure invariants
2369
2370           It is no yet stable enough to be included in a Splint release.
2371           */
2372
2373           /*check that we're in a structure */
2374 #if 0
2375                   /*@unused@*/    uentryList ueL;
2376           /*@unused@*/ uentry ue2;
2377           /*@unused@*/ ctype ct;\r
2378 #endif
2379           fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s)));
2380           ret = sRef_undefined; 
2381 # if 0
2382           
2383           ct = context_getLastStruct ( ct );
2384
2385           llassert( ctype_isStruct(ct) );
2386
2387           ueL =  ctype_getFields (ct);
2388
2389           ue2 = uentryList_lookupField (ueL, s);
2390
2391           if (!uentry_isUndefined(ue2) )
2392             {
2393               ret = uentry_getSref(ue2);
2394               
2395               DPRINTF((
2396                        message("Got field in structure in the annotation constraint: %s (or sref: %s)", s, sRef_unparse(ret) )
2397                        ));
2398               
2399               return ret;
2400             }
2401           
2402 #endif
2403
2404           voptgenerror 
2405             (FLG_UNRECOG, 
2406              message ("Unrecognized identifier in function clause: %s", s), 
2407              loc);
2408
2409           fileloc_free (loc);
2410         }
2411     }
2412   
2413   return ret;
2414 }
2415
2416 sRef modListArrayFetch (/*@exposed@*/ sRef s, /*@unused@*/ sRef mexp)
2417 {
2418   ctype ct = sRef_getType (s);
2419   ctype rt = ctype_realType (ct);
2420
2421   if (ctype_isAP (rt))
2422     {
2423       if (context_inHeader () && ctype_isAbstract (ct))
2424         {
2425           voptgenerror 
2426             (FLG_ABSTRACT,
2427              message
2428              ("Modifies clause in header file indexes abstract "
2429               "type %s (interface modifies clause should not depend "
2430               "on or expose type representation): %q",
2431               ctype_unparse (ct),
2432               sRef_unparse (s)),
2433              g_currentloc);
2434         }
2435       
2436       return (sRef_makeAnyArrayFetch (s));
2437     }
2438   else
2439     {
2440       voptgenerror
2441         (FLG_TYPE,
2442          message
2443          ("Implementation modifies clause uses array fetch on non-array (type %s): %q",
2444           ctype_unparse (ct), sRef_unparse (s)),
2445          g_currentloc);
2446       return s;
2447     }
2448 }
2449
2450 static void clabstract_prepareFunction (uentry e)
2451 {
2452   uentry_checkParams (e);
2453   DPRINTF (("After prepare: %s", uentry_unparseFull (e)));
2454 }
2455
2456 sRef clabstract_checkGlobal (exprNode e)
2457 {
2458   sRef s;
2459   llassert (exprNode_isInitializer (e));
2460
2461   s = exprNode_getSref (e);
2462   DPRINTF (("Initializer: %s -> %s", exprNode_unparse (e), sRef_unparse (s)));
2463
2464   exprNode_free (e);
2465   return sRef_copy (s);
2466 }
This page took 0.216775 seconds and 3 git commands to generate.