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