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