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