2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
27 ** Module for building abstract syntax trees for LCL.
29 ** This module is too close to the surface syntax of LCL.
34 ** Massachusetts Institute of Technology
37 # include "splintMacros.nf"
39 # include "lslparse.h"
40 # include "llgrammar.h" /* need simpleOp, MULOP and logicalOp in makeInfixTermNode */
44 static lsymbol lsymbol_Bool
;
45 static lsymbol lsymbol_bool
;
46 static lsymbol lsymbol_TRUE
;
47 static lsymbol lsymbol_FALSE
;
49 static void lclPredicateNode_free (/*@only@*/ /*@null@*/ lclPredicateNode p_x
) ;
50 static void exposedNode_free (/*@only@*/ /*@null@*/ exposedNode p_x
) ;
51 static void CTypesNode_free (/*@null@*/ /*@only@*/ CTypesNode p_x
);
52 static /*@null@*/ CTypesNode
CTypesNode_copy (/*@null@*/ CTypesNode p_x
) /*@*/ ;
54 constDeclarationNode_free (/*@only@*/ /*@null@*/ constDeclarationNode p_x
);
55 static void claimNode_free (/*@only@*/ /*@null@*/ claimNode p_x
);
56 static void iterNode_free (/*@only@*/ /*@null@*/ iterNode p_x
);
57 static void abstBodyNode_free (/*@only@*/ /*@null@*/ abstBodyNode p_n
);
58 static void abstractNode_free (/*@only@*/ /*@null@*/ abstractNode p_x
);
59 static void taggedUnionNode_free (/*@only@*/ /*@null@*/ taggedUnionNode p_x
);
60 static void typeNode_free (/*@only@*/ /*@null@*/ typeNode p_t
);
61 static /*@null@*/ strOrUnionNode
62 strOrUnionNode_copy (/*@null@*/ strOrUnionNode p_n
) /*@*/ ;
63 static void strOrUnionNode_free (/*@null@*/ /*@only@*/ strOrUnionNode p_n
)
64 /*@modifies *p_n @*/ ;
66 static void enumSpecNode_free (/*@null@*/ /*@only@*/ enumSpecNode p_x
);
67 static /*@only@*/ /*@null@*/ enumSpecNode
68 enumSpecNode_copy (/*@null@*/ enumSpecNode p_x
) /*@*/ ;
69 static /*@only@*/ lclTypeSpecNode
70 lclTypeSpecNode_copySafe (lclTypeSpecNode p_n
) /*@*/ ;
71 static void lclTypeSpecNode_free (/*@null@*/ /*@only@*/ lclTypeSpecNode p_n
);
72 static void typeNamePack_free (/*@only@*/ /*@null@*/ typeNamePack p_x
);
73 static /*@unused@*/ /*@only@*/ cstring
74 opFormNode_unparse (/*@null@*/ opFormNode p_n
) /*@*/ ;
75 static void opFormNode_free (/*@only@*/ /*@null@*/ opFormNode p_op
);
76 static quantifiedTermNode
quantifiedTermNode_copy (quantifiedTermNode p_q
) /*@*/ ;
77 static void nameAndReplaceNode_free (/*@only@*/ /*@null@*/ nameAndReplaceNode p_x
);
78 static void renamingNode_free (/*@only@*/ /*@null@*/ renamingNode p_x
);
79 static void exportNode_free (/*@null@*/ /*@only@*/ exportNode p_x
);
80 static void privateNode_free (/*@only@*/ /*@null@*/ privateNode p_x
);
81 static /*@null@*/ termNode
termNode_copy (/*@null@*/ termNode p_t
) /*@*/ ;
83 stmtNode_free (/*@only@*/ /*@null@*/ stmtNode p_x
) /*@modifies *p_x@*/ ;
84 static /*@null@*/ typeExpr
typeExpr_copy (/*@null@*/ typeExpr p_x
) /*@*/ ;
86 static lsymbol ConditionalSymbol
;
87 static lsymbol equalSymbol
;
88 static lsymbol eqSymbol
;
89 static lclTypeSpecNode exposedType
;
91 static /*@only@*/ cstring
abstDeclaratorNode_unparse (abstDeclaratorNode p_x
);
92 static pairNodeList
extractParams (/*@null@*/ typeExpr p_te
);
93 static sort
extractReturnSort (lclTypeSpecNode p_t
, declaratorNode p_d
);
94 static void checkAssociativity (termNode p_x
, ltoken p_op
);
95 static void LCLBootstrap (void);
96 static cstring
printMiddle (int p_j
);
97 static void paramNode_checkQualifiers (lclTypeSpecNode p_t
, typeExpr p_d
);
99 static /*@only@*/ cstring
enumSpecNode_unparse(/*@null@*/ enumSpecNode p_n
) /*@*/ ;
100 static /*@only@*/ cstring
strOrUnionNode_unparse (/*@null@*/ strOrUnionNode p_n
);
102 static void typeExpr_free (/*@only@*/ /*@null@*/ typeExpr p_x
);
103 static /*@only@*/ cstring
typeExpr_unparseNoBase (/*@null@*/ typeExpr p_x
);
105 void abstDeclaratorNode_free (/*@only@*/ /*@null@*/ abstDeclaratorNode p_x
);
106 # define abstDeclaratorNode_free(x) typeExpr_free(x);
110 resetImports (cstring current
)
112 lsymbolSet_free (g_currentImports
);
114 g_currentImports
= lsymbolSet_new (); /* equal_symbol; */
115 (void) lsymbolSet_insert (g_currentImports
,
116 lsymbol_fromString (current
));
122 typeInfo ti
= (typeInfo
) dmalloc (sizeof (*ti
));
127 ltokenList domain
= ltokenList_new ();
130 equalSymbol
= lsymbol_fromChars ("=");
131 eqSymbol
= lsymbol_fromChars ("\\eq");
134 ** not: cstring_toCharsSafe (context_getBoolName ())
135 ** we use the hard wired "bool" name.
138 lsymbol_bool
= lsymbol_fromChars ("bool");
139 lsymbol_Bool
= lsymbol_fromChars ("Bool");
141 lsymbol_TRUE
= lsymbol_fromChars ("TRUE");
142 lsymbol_FALSE
= lsymbol_fromChars ("FALSE");
144 ConditionalSymbol
= lsymbol_fromChars ("if__then__else__");
146 /* generate operators for
147 ** __ \not, __ \implies __ , __ \and __, __ \or __
150 range
= ltoken_create (simpleId
, lsymbol_bool
);
151 dom
= ltoken_create (simpleId
, lsymbol_bool
);
153 ltokenList_addh (domain
, ltoken_copy (dom
));
155 domain2
= ltokenList_copy (domain
); /* moved this here (before release) */
157 sign
= makesigNode (ltoken_undefined
, domain
, ltoken_copy (range
));
159 opform
= makeOpFormNode (ltoken_undefined
, OPF_ANYOPM
,
160 opFormUnion_createAnyOp (ltoken_not
),
162 nn
= makeNameNodeForm (opform
);
163 symtable_enterOp (g_symtab
, nn
, sign
);
165 ltokenList_addh (domain2
, dom
);
167 sign
= makesigNode (ltoken_undefined
, domain2
, range
);
169 opform
= makeOpFormNode (ltoken_undefined
, OPF_MANYOPM
,
170 opFormUnion_createAnyOp (ltoken_and
),
173 nn
= makeNameNodeForm (opform
);
174 symtable_enterOp (g_symtab
, nn
, sigNode_copy (sign
));
176 opform
= makeOpFormNode (ltoken_undefined
, OPF_MANYOPM
,
177 opFormUnion_createAnyOp (ltoken_or
),
180 nn
= makeNameNodeForm (opform
);
181 symtable_enterOp (g_symtab
, nn
, sigNode_copy (sign
));
183 opform
= makeOpFormNode (ltoken_undefined
, OPF_MANYOPM
,
184 opFormUnion_createAnyOp (ltoken_implies
),
186 nn
= makeNameNodeForm (opform
);
187 symtable_enterOp (g_symtab
, nn
, sign
);
189 /* from lclscanline.c's init procedure */
190 /* comment out so we can add in lclinit.lci: synonym double float */
191 /* ReserveToken (FLOAT, "float"); */
192 /* But we need to make the scanner parse "float" not as a simpleId, but
193 as a TYPEDEF_NAME. This is done later in abstract_init */
195 ti
->id
= ltoken_createType (LLT_TYPEDEF_NAME
, SID_TYPE
, lsymbol_fromChars ("float"));
197 ti
->modifiable
= FALSE
;
198 ti
->abstract
= FALSE
;
199 ti
->export
= FALSE
; /* this is implicit, not exported */
200 ti
->basedOn
= g_sortFloat
;
201 symtable_enterType (g_symtab
, ti
);
205 declareForwardType (declaratorNode declare
)
207 typeInfo ti
= (typeInfo
) dmalloc (sizeof (*ti
));
211 typedefname
= ltoken_getText (declare
->id
);
212 ti
->id
= ltoken_copy (declare
->id
);
214 ltoken_setCode (ti
->id
, LLT_TYPEDEF_NAME
);
215 ltoken_setIdType (ti
->id
, SID_TYPE
);
217 ti
->modifiable
= FALSE
;
218 ti
->abstract
= FALSE
;
219 tsort
= lclTypeSpecNode2sort (exposedType
);
220 handle
= typeExpr2ptrSort (tsort
, declare
->type
);
221 ti
->basedOn
= sort_makeSyn (declare
->id
, handle
, typedefname
);
224 symtable_enterType (g_symtab
, ti
);
227 void LCLBuiltins (void)
229 typeInfo ti
= (typeInfo
) dmalloc (sizeof (*ti
));
230 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
232 /* immutable type bool;
234 constant bool FALSE = false;
235 constant bool TRUE = true; */
237 /* the following defines the builtin LSL sorts and operators */
240 /* now LCL builtin proper */
241 /* do "immutable type bool;" */
243 ti
->id
= ltoken_copy (ltoken_bool
);
245 ltoken_setCode (ti
->id
, LLT_TYPEDEF_NAME
);
246 ltoken_setIdType (ti
->id
, SID_TYPE
);
248 ti
->modifiable
= FALSE
;
250 ti
->basedOn
= g_sortBool
;
251 ti
->export
= FALSE
; /* this wasn't set (detected by Splint) */
252 symtable_enterType (g_symtab
, ti
);
254 /* do "constant bool FALSE = false;" */
255 vi
->id
= ltoken_createType (simpleId
, SID_VAR
, lsymbol_fromChars ("FALSE"));
257 vi
->kind
= VRK_CONST
;
258 vi
->sort
= g_sortBool
;
261 (void) symtable_enterVar (g_symtab
, vi
);
263 /* do "constant bool TRUE = true;" */
264 /* vi->id = ltoken_copy (vi->id); */
265 ltoken_setText (vi
->id
, lsymbol_fromChars ("TRUE"));
266 (void) symtable_enterVar (g_symtab
, vi
);
281 ** Minimal we need to bootstrap is to provide the sort
282 ** "bool" and 2 bool constants "true" and "false".
283 ** sort_init should already have been called, and hence
284 ** the bool and Bool sorts defined.
287 (void) sort_makeImmutable (ltoken_undefined
, lsymbol_bool
);
288 range
= ltoken_create (simpleId
, lsymbol_bool
);
289 sign
= makesigNode (ltoken_undefined
, ltokenList_new (), range
);
291 nn1
= (nameNode
) dmalloc (sizeof (*nn1
));
294 nn1
->content
.opid
= ltoken_create (simpleId
, lsymbol_fromChars ("true"));
296 symtable_enterOp (g_symtab
, nn1
, sign
);
298 nn2
= (nameNode
) dmalloc (sizeof (*nn2
));
300 nn2
->content
.opid
= ltoken_create (simpleId
, lsymbol_fromChars ("false"));
302 symtable_enterOp (g_symtab
, nn2
, sigNode_copy (sign
));
306 consInterfaceNode (/*@only@*/ interfaceNode n
, /*@returned@*/ interfaceNodeList ns
)
308 /* n is never empty, but ns may be empty */
309 interfaceNodeList_addl (ns
, n
);
313 /*@only@*/ interfaceNode
314 makeInterfaceNodeImports (/*@only@*/ importNodeList x
)
316 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
317 lsymbol importSymbol
;
319 i
->kind
= INF_IMPORTS
;
320 i
->content
.imports
= x
; /* an importNodeList */
322 importNodeList_elements (x
, imp
)
324 importSymbol
= ltoken_getRawText (imp
->val
);
326 if (lsymbolSet_member (g_currentImports
, importSymbol
))
329 message ("Circular imports: %s",
330 cstring_fromChars (lsymbol_toChars (importSymbol
))));
334 processImport (importSymbol
, imp
->val
, imp
->kind
);
336 } end_importNodeList_elements
;
338 lhOutLine (cstring_undefined
);
342 /*@only@*/ interfaceNode
343 makeInterfaceNodeUses (/*@only@*/ traitRefNodeList x
)
345 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
349 /* read in LSL traits */
354 /*@only@*/ interfaceNode
355 interfaceNode_makeConst (/*@only@*/ constDeclarationNode x
)
357 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
358 exportNode e
= (exportNode
) dmalloc (sizeof (*e
));
361 e
->content
.constdeclaration
= x
;
362 i
->kind
= INF_EXPORT
;
363 i
->content
.export
= e
;
368 /*@only@*/ interfaceNode
369 interfaceNode_makeVar (/*@only@*/ varDeclarationNode x
)
371 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
372 exportNode e
= (exportNode
) dmalloc (sizeof (*e
));
375 e
->content
.vardeclaration
= x
;
376 i
->kind
= INF_EXPORT
;
377 i
->content
.export
= e
;
379 if (context_msgLh ())
381 lhOutLine (lhVarDecl (x
->type
, x
->decls
, x
->qualifier
));
387 /*@only@*/ interfaceNode
388 interfaceNode_makeType (/*@only@*/ typeNode x
)
390 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
391 exportNode e
= (exportNode
) dmalloc (sizeof (*e
));
394 i
->kind
= INF_EXPORT
;
395 i
->content
.export
= e
;
397 if (context_msgLh ())
400 lhOutLine (lhType (x
));
406 /*@only@*/ interfaceNode
407 interfaceNode_makeFcn (/*@only@*/ fcnNode x
)
409 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
410 exportNode e
= (exportNode
) dmalloc (sizeof (*e
));
414 i
->kind
= INF_EXPORT
;
415 i
->content
.export
= e
;
417 if (context_msgLh ())
419 llassert (x
->typespec
!= NULL
);
420 llassert (x
->declarator
!= NULL
);
422 lhOutLine (lhFunction (x
->typespec
, x
->declarator
));
428 /*@only@*/ interfaceNode
429 interfaceNode_makeClaim (/*@only@*/ claimNode x
)
431 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
432 exportNode e
= (exportNode
) dmalloc (sizeof (*e
));
435 e
->content
.claim
= x
;
436 i
->kind
= INF_EXPORT
;
437 i
->content
.export
= e
;
441 /*@only@*/ interfaceNode
442 interfaceNode_makeIter (/*@only@*/ iterNode x
)
444 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
445 exportNode e
= (exportNode
) dmalloc (sizeof (*e
));
449 i
->kind
= INF_EXPORT
;
450 i
->content
.export
= e
;
454 /*@only@*/ interfaceNode
455 interfaceNode_makePrivConst (/*@only@*/ constDeclarationNode x
)
457 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
458 privateNode e
= (privateNode
) dmalloc (sizeof (*e
));
460 e
->kind
= PRIV_CONST
;
461 e
->content
.constdeclaration
= x
;
462 i
->kind
= INF_PRIVATE
;
463 i
->content
.private = e
;
467 /*@only@*/ interfaceNode
468 interfaceNode_makePrivVar (/*@only@*/ varDeclarationNode x
)
470 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
471 privateNode e
= (privateNode
) dmalloc (sizeof (*e
));
474 e
->content
.vardeclaration
= x
;
475 i
->kind
= INF_PRIVATE
;
476 i
->content
.private = e
;
480 /*@only@*/ interfaceNode
481 interfaceNode_makePrivType (/*@only@*/ typeNode x
)
483 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
484 privateNode e
= (privateNode
) dmalloc (sizeof (*e
));
488 i
->kind
= INF_PRIVATE
;
489 i
->content
.private = e
;
493 /*@only@*/ interfaceNode
494 interfaceNode_makePrivFcn (/*@only@*/ fcnNode x
)
496 interfaceNode i
= (interfaceNode
) dmalloc (sizeof (*i
));
497 privateNode e
= (privateNode
) dmalloc (sizeof (*e
));
500 ** bug detected by enum checking
501 ** e->kind = XPK_FCN;
504 e
->kind
= PRIV_FUNCTION
;
506 i
->kind
= INF_PRIVATE
;
507 i
->content
.private = e
;
513 exportNode_unparse (exportNode n
)
515 if (n
!= (exportNode
) 0)
522 constDeclarationNode_unparse (n
->content
.constdeclaration
)));
526 varDeclarationNode_unparse (n
->content
.vardeclaration
)));
528 return (message ("%q\n", typeNode_unparse (n
->content
.type
)));
530 return (fcnNode_unparse (n
->content
.fcn
));
532 return (claimNode_unparse (n
->content
.claim
));
534 return (iterNode_unparse (n
->content
.iter
));
536 llfatalbug (message ("exportNode_unparse: unknown kind: %d", (int) n
->kind
));
539 return cstring_undefined
;
543 privateNode_unparse (privateNode n
)
545 if (n
!= (privateNode
) 0)
550 return (constDeclarationNode_unparse (n
->content
.constdeclaration
));
552 return (varDeclarationNode_unparse (n
->content
.vardeclaration
));
554 return (typeNode_unparse (n
->content
.type
));
556 return (fcnNode_unparse (n
->content
.fcn
));
558 llfatalbug (message ("privateNode_unparse: unknown kind: %d",
562 return cstring_undefined
;
564 # endif /* DEADCODE */
566 void lclPredicateNode_free (/*@null@*/ /*@only@*/ lclPredicateNode x
)
570 termNode_free (x
->predicate
);
571 ltoken_free (x
->tok
);
577 static /*@only@*/ cstring
578 lclPredicateNode_unparse (/*@null@*/ lclPredicateNode p
) /*@*/
580 if (p
!= (lclPredicateNode
) 0)
582 cstring st
= cstring_undefined
;
587 st
= cstring_makeLiteral (" requires ");
590 st
= cstring_makeLiteral (" checks ");
593 st
= cstring_makeLiteral (" ensures ");
596 st
= cstring_makeLiteral (" claims ");
599 st
= cstring_makeLiteral ("constraint ");
602 st
= cstring_makeLiteral ("initially ");
607 llfatalbug (message ("lclPredicateNode_unparse: unknown kind: %d",
610 return (message ("%q%q;\n", st
, termNode_unparse (p
->predicate
)));
612 return cstring_undefined
;
614 # endif /* DEADCODE */
617 ltoken_similar (ltoken t1
, ltoken t2
)
619 lsymbol sym1
= ltoken_getText (t1
);
620 lsymbol sym2
= ltoken_getText (t2
);
627 if ((sym1
== eqSymbol
&& sym2
== equalSymbol
) ||
628 (sym2
== eqSymbol
&& sym1
== equalSymbol
))
633 if ((sym1
== lsymbol_bool
&& sym2
== lsymbol_Bool
) ||
634 (sym2
== lsymbol_bool
&& sym1
== lsymbol_Bool
))
644 iterNode_unparse (/*@null@*/ iterNode i
)
646 if (i
!= (iterNode
) 0)
648 return (message ("iter %s %q", ltoken_unparse (i
->name
),
649 paramNodeList_unparse (i
->params
)));
651 return cstring_undefined
;
656 fcnNode_unparse (/*@null@*/ fcnNode f
)
658 if (f
!= (fcnNode
) 0)
660 return (message ("%q %q%q{\n%q%q%q%q%q%q}\n",
661 lclTypeSpecNode_unparse (f
->typespec
),
662 declaratorNode_unparse (f
->declarator
),
663 varDeclarationNodeList_unparse (f
->globals
),
664 varDeclarationNodeList_unparse (f
->inits
),
665 letDeclNodeList_unparse (f
->lets
),
666 lclPredicateNode_unparse (f
->require
),
667 modifyNode_unparse (f
->modify
),
668 lclPredicateNode_unparse (f
->ensures
),
669 lclPredicateNode_unparse (f
->claim
)));
671 return cstring_undefined
;
675 varDeclarationNode_unparse (/*@null@*/ varDeclarationNode x
)
677 if (x
!= (varDeclarationNode
) 0)
683 return (sRef_unparse (x
->sref
));
687 switch (x
->qualifier
)
690 st
= cstring_undefined
;
693 st
= cstring_makeLiteral ("const ");
696 st
= cstring_makeLiteral ("volatile ");
701 st
= message ("%q%q %q", st
, lclTypeSpecNode_unparse (x
->type
),
702 initDeclNodeList_unparse (x
->decls
));
707 return cstring_undefined
;
711 typeNode_unparse (/*@null@*/ typeNode t
)
713 if (t
!= (typeNode
) 0)
718 return (abstractNode_unparse (t
->content
.abstract
));
720 return (exposedNode_unparse (t
->content
.exposed
));
722 return (taggedUnionNode_unparse (t
->content
.taggedunion
));
724 llfatalbug (message ("typeNode_unparse: unknown kind: %d", (int)t
->kind
));
727 return cstring_undefined
;
731 constDeclarationNode_unparse (/*@null@*/ constDeclarationNode x
)
733 if (x
!= (constDeclarationNode
) 0)
735 return (message ("constant %q %q", lclTypeSpecNode_unparse (x
->type
),
736 initDeclNodeList_unparse (x
->decls
)));
739 return cstring_undefined
;
741 # endif /* DEADCODE */
743 /*@only@*/ storeRefNode
744 makeStoreRefNodeTerm (/*@only@*/ termNode t
)
746 storeRefNode x
= (storeRefNode
) dmalloc (sizeof (*x
));
753 /*@only@*/ storeRefNode
754 makeStoreRefNodeType (/*@only@*/ lclTypeSpecNode t
, bool isObj
)
756 storeRefNode x
= (storeRefNode
) dmalloc (sizeof (*x
));
758 x
->kind
= isObj
? SRN_OBJ
: SRN_TYPE
;
764 makeStoreRefNodeInternal (void)
766 storeRefNode x
= (storeRefNode
) dmalloc (sizeof (*x
));
768 x
->kind
= SRN_SPECIAL
;
769 x
->content
.ref
= sRef_makeInternalState ();
774 makeStoreRefNodeSystem (void)
776 storeRefNode x
= (storeRefNode
) dmalloc (sizeof (*x
));
778 x
->kind
= SRN_SPECIAL
;
779 x
->content
.ref
= sRef_makeSystemState ();
783 /*@only@*/ modifyNode
784 makeModifyNodeSpecial (/*@only@*/ ltoken t
, bool modifiesNothing
)
786 modifyNode x
= (modifyNode
) dmalloc (sizeof (*x
));
789 x
->modifiesNothing
= modifiesNothing
;
790 x
->hasStoreRefList
= FALSE
;
794 /*@only@*/ modifyNode
795 makeModifyNodeRef (/*@only@*/ ltoken t
, /*@only@*/ storeRefNodeList y
)
797 modifyNode x
= (modifyNode
) dmalloc (sizeof (*x
));
801 x
->hasStoreRefList
= TRUE
;
802 x
->modifiesNothing
= FALSE
;
804 /* check that all storeRef's are modifiable */
806 storeRefNodeList_elements (y
, sr
)
808 if (storeRefNode_isTerm (sr
))
810 sort
= sr
->content
.term
->sort
;
812 if (!sort_mutable (sort
) && sort_isValidSort (sort
))
814 ltoken errtok
= termNode_errorToken (sr
->content
.term
);
816 message ("Term denoting immutable object used in modifies list: %q",
817 termNode_unparse (sr
->content
.term
)));
822 if (!storeRefNode_isSpecial (sr
))
824 sort
= lclTypeSpecNode2sort (sr
->content
.type
);
826 if (storeRefNode_isObj (sr
))
828 sort
= sort_makeObj (sort
);
831 if (!sort_mutable (sort
))
833 ltoken errtok
= lclTypeSpecNode_errorToken (sr
->content
.type
);
835 message ("Immutable type used in modifies list: %q",
836 sort_unparse (sort
)));
840 } end_storeRefNodeList_elements
;
844 /*@observer@*/ ltoken
845 termNode_errorToken (/*@null@*/ termNode n
)
847 if (n
!= (termNode
) 0)
852 case TRM_UNCHANGEDALL
:
853 case TRM_UNCHANGEDOTHERS
:
857 case TRM_ZEROARY
: /* also the default kind, when no in symbol table */
860 return n
->quantified
->open
;
861 case TRM_APPLICATION
:
866 return n
->name
->content
.opid
;
870 llassert (n
->name
->content
.opform
!= NULL
);
871 return n
->name
->content
.opform
->tok
;
876 return ltoken_undefined
;
880 return ltoken_undefined
;
883 /*@observer@*/ ltoken
884 nameNode_errorToken (/*@null@*/ nameNode nn
)
886 if (nn
!= (nameNode
) 0)
890 return nn
->content
.opid
;
894 if (nn
->content
.opform
!= NULL
)
896 return nn
->content
.opform
->tok
;
901 return ltoken_undefined
;
904 /*@observer@*/ ltoken
905 lclTypeSpecNode_errorToken (/*@null@*/ lclTypeSpecNode t
)
907 if (t
!= (lclTypeSpecNode
) 0)
913 llassert (t
->content
.type
!= NULL
);
915 if (ltokenList_empty (t
->content
.type
->ctypes
))
918 return (ltokenList_head (t
->content
.type
->ctypes
));
920 case LTS_STRUCTUNION
:
921 llassert (t
->content
.structorunion
!= NULL
);
922 return t
->content
.structorunion
->tok
;
924 llassert (t
->content
.enumspec
!= NULL
);
925 return t
->content
.enumspec
->tok
;
927 return (lclTypeSpecNode_errorToken (t
->content
.conj
->a
));
931 return ltoken_undefined
;
935 sort_member_modulo_cstring (sort s
, /*@null@*/ termNode t
)
938 if (t
!= (termNode
) 0)
940 if (t
->kind
== TRM_LITERAL
)
941 { /* allow multiple types */
944 sortSet_elements (t
->possibleSorts
, el
)
946 if (sort_compatible_modulo_cstring (s
, el
))
950 } end_sortSet_elements
;
952 sn
= sort_lookup (s
);
954 if (sn
->kind
== SRT_PTR
)
956 char *lit
= lsymbol_toChars (ltoken_getText (t
->literal
));
962 if (sscanf (lit
, "%ld", &val
) == 1)
964 if (val
== 0) return TRUE
;
973 return sort_compatible_modulo_cstring (s
, t
->sort
);
979 /*@only@*/ letDeclNode
980 makeLetDeclNode (ltoken varid
, /*@only@*/ /*@null@*/ lclTypeSpecNode t
,
981 /*@only@*/ termNode term
)
983 letDeclNode x
= (letDeclNode
) dmalloc (sizeof (*x
));
984 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
988 if (t
!= (lclTypeSpecNode
) 0)
991 /* check varid has the same sort as term */
992 s
= lclTypeSpecNode2sort (t
);
993 /* termsort = term->sort; */
994 /* should keep the arguments in order */
995 if (!sort_member_modulo_cstring (s
, term
) &&
996 !term
->error_reported
)
998 errtok
= termNode_errorToken (term
);
1000 /* errorShowPoint (inputStream_thisLine (lclsource), ltoken_getCol (errtok)); */
1001 /* sprintf (ERRMSG, "expect `%s' type but given term has `%s' type",
1002 sort_unparse (s), sort_unparse (termsort)); */
1005 message ("Let declaration expects type %q", sort_unparse (s
)));
1006 /* evs --- don't know how to generated this message or what it means? */
1013 /* assign variable its type and sort, store in symbol table */
1014 vi
->id
= ltoken_copy (varid
);
1019 (void) symtable_enterVar (g_symtab
, vi
);
1025 x
->sort
= sort_makeNoSort ();
1030 /*@only@*/ programNode
1031 makeProgramNodeAction (/*@only@*/ programNodeList x
, actionKind k
)
1033 programNode n
= (programNode
) dmalloc (sizeof (*n
));
1036 n
->content
.args
= x
;
1040 /*@only@*/ programNode
1041 makeProgramNode (/*@only@*/ stmtNode x
)
1043 programNode n
= (programNode
) dmalloc (sizeof (*n
));
1047 n
->content
.self
= x
;
1052 makeAbstractTypeNode (/*@only@*/ abstractNode x
)
1054 typeNode n
= (typeNode
) dmalloc (sizeof (*n
));
1056 n
->kind
= TK_ABSTRACT
;
1057 n
->content
.abstract
= x
;
1063 makeExposedTypeNode (/*@only@*/ exposedNode x
)
1065 typeNode n
= (typeNode
) dmalloc (sizeof (*n
));
1067 n
->kind
= TK_EXPOSED
;
1068 n
->content
.exposed
= x
;
1073 ** evs added 8 Sept 1993
1076 /*@only@*/ importNode
1077 importNode_makePlain (/*@only@*/ ltoken t
)
1079 importNode imp
= (importNode
) dmalloc (sizeof (*imp
));
1081 imp
->kind
= IMPPLAIN
;
1086 /*@only@*/ importNode
1087 importNode_makeBracketed (/*@only@*/ ltoken t
)
1089 importNode imp
= (importNode
) dmalloc (sizeof (*imp
));
1091 imp
->kind
= IMPBRACKET
;
1096 static cstring
extractQuote (/*@only@*/ cstring s
)
1098 size_t len
= cstring_length (s
);
1099 char *sc
= cstring_toCharsSafe (s
);
1103 *(sc
+ len
- 1) = '\0';
1104 t
= cstring_fromChars (mstring_copy (sc
+ 1));
1109 /*@only@*/ importNode
1110 importNode_makeQuoted (/*@only@*/ ltoken t
)
1112 importNode imp
= (importNode
) dmalloc (sizeof (*imp
));
1113 cstring q
= extractQuote (cstring_copy (ltoken_getRawString (t
)));
1115 imp
->kind
= IMPQUOTE
;
1117 ltoken_setRawText (t
, lsymbol_fromString (q
));
1125 /*@only@*/ traitRefNode
1126 makeTraitRefNode (/*@only@*/ ltokenList fl
, /*@only@*/ renamingNode r
)
1128 traitRefNode n
= (traitRefNode
) dmalloc (sizeof (*n
));
1136 ** printLeaves: no commas
1139 static /*@only@*/ cstring
1140 printLeaves (ltokenList f
)
1142 bool firstone
= TRUE
;
1143 cstring s
= cstring_undefined
;
1145 ltokenList_elements (f
, i
)
1149 s
= cstring_copy (ltoken_unparse (i
));
1154 s
= message ("%q %s", s
, ltoken_unparse (i
));
1156 } end_ltokenList_elements
;
1163 printLeaves2 (ltokenList f
)
1165 return (ltokenList_unparse (f
));
1169 printRawLeaves2 (ltokenList f
)
1172 cstring s
= cstring_undefined
;
1174 ltokenList_elements (f
, i
)
1178 s
= message ("%s", ltoken_getRawString (i
));
1182 s
= message ("%q, %s", s
, ltoken_getRawString (i
));
1183 } end_ltokenList_elements
;
1188 /*@only@*/ renamingNode
1189 makeRenamingNode (/*@only@*/ typeNameNodeList n
, /*@only@*/ replaceNodeList r
)
1191 renamingNode ren
= (renamingNode
) dmalloc (sizeof (*ren
));
1193 if (typeNameNodeList_empty (n
))
1195 ren
->is_replace
= TRUE
;
1196 ren
->content
.replace
= r
;
1197 typeNameNodeList_free (n
);
1201 nameAndReplaceNode nr
= (nameAndReplaceNode
) dmalloc (sizeof (*nr
));
1202 nr
->replacelist
= r
;
1204 ren
->is_replace
= FALSE
;
1205 ren
->content
.name
= nr
;
1213 renamingNode_unparse (/*@null@*/ renamingNode x
)
1215 if (x
!= (renamingNode
) 0)
1219 return (replaceNodeList_unparse (x
->content
.replace
));
1223 return (message ("%q%q", typeNameNodeList_unparse (x
->content
.name
->namelist
),
1224 replaceNodeList_unparse (x
->content
.name
->replacelist
)));
1227 return cstring_undefined
;
1229 # endif /* DEADCODE */
1231 /*@only@*/ replaceNode
1232 makeReplaceNameNode (ltoken t
, typeNameNode tn
, nameNode nn
)
1234 replaceNode r
= (replaceNode
) dmalloc (sizeof (*r
));
1239 r
->content
.renamesortname
.name
= nn
;
1240 r
->content
.renamesortname
.signature
= (sigNode
) NULL
;
1245 /*@only@*/ replaceNode
1246 makeReplaceNode (ltoken t
, typeNameNode tn
,
1247 bool is_ctype
, ltoken ct
,
1248 nameNode nn
, sigNode sn
)
1250 replaceNode r
= (replaceNode
) dmalloc (sizeof (*r
));
1253 r
->isCType
= is_ctype
;
1258 r
->content
.ctype
= ct
;
1264 r
->content
.renamesortname
.name
= nn
;
1265 r
->content
.renamesortname
.signature
= sn
;
1274 replaceNode_unparse (/*@null@*/ replaceNode x
)
1276 if (x
!= (replaceNode
) 0)
1280 st
= message ("%q for ", typeNameNode_unparse (x
->typename
));
1284 st
= message ("%q%s", st
, ltoken_getRawString (x
->content
.ctype
));
1288 st
= message ("%q%q%q", st
, nameNode_unparse (x
->content
.renamesortname
.name
),
1289 sigNode_unparse (x
->content
.renamesortname
.signature
));
1293 return cstring_undefined
;
1295 # endif /* DEADCODE */
1298 makeNameNodeForm (/*@only@*/ /*@null@*/ opFormNode opform
)
1300 nameNode nn
= (nameNode
) dmalloc (sizeof (*nn
));
1303 nn
->content
.opform
= opform
;
1309 makeNameNodeId (/*@only@*/ ltoken opid
)
1311 nameNode nn
= (nameNode
) dmalloc (sizeof (*nn
));
1314 ** current LSL -syms output bug produces "if_then_else_" rather
1315 ** than 6 separate tokens
1318 if (ltoken_getText (opid
) == ConditionalSymbol
)
1320 opFormNode opform
= makeOpFormNode (ltoken_undefined
, OPF_IF
,
1321 opFormUnion_createMiddle (0),
1324 nn
->content
.opform
= opform
;
1330 nn
->content
.opid
= opid
;
1337 nameNode_unparse (/*@null@*/ nameNode n
)
1339 if (n
!= (nameNode
) 0)
1343 return (cstring_copy (ltoken_getRawString (n
->content
.opid
))); /*!!!*/
1347 return (opFormNode_unparse (n
->content
.opform
));
1350 return cstring_undefined
;
1354 makesigNode (ltoken t
, /*@only@*/ ltokenList domain
, ltoken range
)
1356 sigNode s
= (sigNode
) dmalloc (sizeof (*s
));
1357 unsigned long int key
;
1360 ** Assign a hash key here to speed up lookup of operators.
1366 key
= MASH (0, ltoken_getText (range
));
1368 ltokenList_elements (domain
, id
)
1370 lsymbol sym
= ltoken_getText (id
);
1371 key
= MASH (key
, sym
);
1372 } end_ltokenList_elements
;
1378 cstring
sigNode_unparse (/*@null@*/ sigNode n
)
1380 if (n
!= (sigNode
) 0)
1382 return (message (":%q -> %s", printLeaves2 (n
->domain
),
1383 ltoken_unparse (n
->range
)));
1386 return cstring_undefined
;
1389 void sigNode_markOwned (sigNode n
)
1391 sfreeEventually (n
);
1395 sigNode_unparseText (/*@null@*/ sigNode n
)
1397 if (n
!= (sigNode
) 0)
1399 return (message ("%q -> %s", printLeaves2 (n
->domain
),
1400 ltoken_unparse (n
->range
)));
1402 return cstring_undefined
;
1405 static unsigned long opFormNode2key (opFormNode op
, opFormKind k
)
1407 unsigned long int key
;
1412 /* OPF_IF is the first enum, so it's 0 */
1415 key
= MASH (k
, k
+ 1);
1423 { /* treat eq and = the same */
1424 lsymbol sym
= ltoken_getText (op
->content
.anyop
);
1426 if (sym
== equalSymbol
)
1428 key
= MASH (k
, eqSymbol
);
1432 key
= MASH (k
, ltoken_getText (op
->content
.anyop
));
1444 key
= MASH (k
, op
->content
.middle
);
1445 key
= MASH (key
, ltoken_getRawText (op
->tok
));
1451 key
= MASH (k
, ltoken_getRawText (op
->content
.id
));
1460 /*@only@*/ opFormNode
1461 makeOpFormNode (ltoken t
, opFormKind k
, opFormUnion u
,
1464 opFormNode n
= (opFormNode
) dmalloc (sizeof (*n
));
1465 unsigned long int key
= 0;
1468 ** Assign a hash key here to speed up lookup of operators.
1478 n
->content
.middle
= 0;
1479 /* OPF_IF is the first enum, so it's 0 */
1480 key
= MASH
/*@+enumint@*/ (k
, k
+ 1) /*@=enumint@*/;
1486 { /* treat eq and = the same */
1487 lsymbol sym
= ltoken_getText (u
.anyop
);
1489 if (sym
== equalSymbol
)
1491 key
= MASH (k
, eqSymbol
);
1495 key
= MASH (k
, ltoken_getText (u
.anyop
));
1510 key
= MASH (k
, u
.middle
);
1511 key
= MASH (key
, ltoken_getRawText (t
));
1517 key
= MASH (k
, ltoken_getRawText (u
.id
));
1522 llbug (message ("makeOpFormNode: unknown opFormKind: %d", (int) k
));
1529 static cstring
printMiddle (int j
)
1532 char *s
= mstring_createEmpty ();
1534 for (i
= j
; i
>= 1; i
--)
1536 s
= mstring_concatFree1 (s
, "__");
1540 s
= mstring_concatFree1 (s
, ", ");
1544 return cstring_fromCharsO (s
);
1547 static /*@only@*/ cstring
1548 opFormNode_unparse (/*@null@*/ opFormNode n
)
1550 if (n
!= (opFormNode
) 0)
1555 return (cstring_makeLiteral ("if __ then __ else __ "));
1557 return (cstring_copy (ltoken_getRawString (n
->content
.anyop
)));
1559 return (message ("__ %s", ltoken_getRawString (n
->content
.anyop
)));
1561 return (message ("%s __ ", ltoken_getRawString (n
->content
.anyop
)));
1563 return (message ("__ %s __ ", ltoken_getRawString (n
->content
.anyop
)));
1565 return (message ("%s %q %s",
1566 ltoken_getRawString (n
->tok
),
1567 printMiddle (n
->content
.middle
),
1568 ltoken_getRawString (n
->close
)));
1570 return (message ("__ %s %q %s",
1571 ltoken_getRawString (n
->tok
),
1572 printMiddle (n
->content
.middle
),
1573 ltoken_getRawString (n
->close
)));
1575 return (message ("%s %q %s __",
1576 ltoken_getRawString (n
->tok
),
1577 printMiddle (n
->content
.middle
),
1578 ltoken_getRawString (n
->close
)));
1580 return (message ("__ %s%q %s __",
1581 ltoken_getRawString (n
->tok
),
1582 printMiddle (n
->content
.middle
),
1583 ltoken_getRawString (n
->close
)));
1585 return (message ("[%q]", printMiddle (n
->content
.middle
)));
1587 return (message ("__ [%q]", printMiddle (n
->content
.middle
)));
1589 return (message ("[%q] __", printMiddle (n
->content
.middle
)));
1591 return (message ("__ [%q] __", printMiddle (n
->content
.middle
)));
1593 return (message (" \\select %s", ltoken_getRawString (n
->content
.id
)));
1595 return (message (" \\field_arrow%s", ltoken_getRawString (n
->content
.id
)));
1597 return (message ("__ \\select %s", ltoken_getRawString (n
->content
.id
)));
1599 return (message ("__ \\field_arrow %s", ltoken_getRawString (n
->content
.id
)));
1601 llfatalbug (message ("opFormNodeUnparse: unknown kind: %d",
1605 return cstring_undefined
;
1608 /*@only@*/ typeNameNode
1609 makeTypeNameNode (bool isObj
, lclTypeSpecNode t
, abstDeclaratorNode n
)
1611 typeNameNode tn
= (typeNameNode
) dmalloc (sizeof (*tn
));
1612 typeNamePack p
= (typeNamePack
) dmalloc (sizeof (*p
));
1614 tn
->isTypeName
= TRUE
;
1618 tn
->opform
= (opFormNode
) 0;
1623 /*@only@*/ typeNameNode
1624 makeTypeNameNodeOp (opFormNode n
)
1626 typeNameNode t
= (typeNameNode
) dmalloc (sizeof (*t
));
1627 t
->typename
= (typeNamePack
) 0;
1629 t
->isTypeName
= FALSE
;
1634 typeNameNode_unparse (/*@null@*/ typeNameNode n
)
1636 if (n
!= (typeNameNode
) 0)
1640 cstring st
= cstring_undefined
;
1641 typeNamePack p
= n
->typename
;
1643 llassert (p
!= NULL
);
1646 st
= cstring_makeLiteral ("obj ");
1648 return (message ("%q%q%q", st
, lclTypeSpecNode_unparse (p
->type
),
1649 abstDeclaratorNode_unparse (p
->abst
)));
1653 return (opFormNode_unparse (n
->opform
));
1655 return cstring_undefined
;
1658 /*@only@*/ lclTypeSpecNode
1659 makeLclTypeSpecNodeConj (/*@null@*/ lclTypeSpecNode a
, /*@null@*/ lclTypeSpecNode b
)
1661 lclTypeSpecNode n
= (lclTypeSpecNode
) dmalloc (sizeof (*n
));
1664 n
->pointers
= pointers_undefined
;
1665 n
->quals
= qualList_new ();
1666 n
->content
.conj
= (lclconj
) dmalloc (sizeof (*n
->content
.conj
));
1667 n
->content
.conj
->a
= a
;
1668 n
->content
.conj
->b
= b
;
1673 /*@only@*/ lclTypeSpecNode
1674 makeLclTypeSpecNodeType (/*@null@*/ CTypesNode x
)
1676 lclTypeSpecNode n
= (lclTypeSpecNode
) dmalloc (sizeof (*n
));
1679 n
->pointers
= pointers_undefined
;
1680 n
->content
.type
= x
;
1681 n
->quals
= qualList_new ();
1685 /*@only@*/ lclTypeSpecNode
1686 makeLclTypeSpecNodeSU (/*@null@*/ strOrUnionNode x
)
1688 lclTypeSpecNode n
= (lclTypeSpecNode
) dmalloc (sizeof (*n
));
1690 n
->kind
= LTS_STRUCTUNION
;
1691 n
->pointers
= pointers_undefined
;
1692 n
->content
.structorunion
= x
;
1693 n
->quals
= qualList_new ();
1697 /*@only@*/ lclTypeSpecNode
1698 makeLclTypeSpecNodeEnum (/*@null@*/ enumSpecNode x
)
1700 lclTypeSpecNode n
= (lclTypeSpecNode
) dmalloc (sizeof (*n
));
1702 n
->quals
= qualList_new ();
1704 n
->pointers
= pointers_undefined
;
1705 n
->content
.enumspec
= x
;
1710 lclTypeSpecNode_addQual (lclTypeSpecNode n
, qual q
)
1712 llassert (lclTypeSpecNode_isDefined (n
));
1713 n
->quals
= qualList_add (n
->quals
, q
);
1718 lclTypeSpecNode_unparse (/*@null@*/ lclTypeSpecNode n
)
1720 if (n
!= (lclTypeSpecNode
) 0)
1725 llassert (n
->content
.type
!= NULL
);
1726 return (printLeaves (n
->content
.type
->ctypes
));
1727 case LTS_STRUCTUNION
:
1728 return (strOrUnionNode_unparse (n
->content
.structorunion
));
1730 return (enumSpecNode_unparse (n
->content
.enumspec
));
1732 return (lclTypeSpecNode_unparse (n
->content
.conj
->a
));
1734 llfatalbug (message ("lclTypeSpecNode_unparse: unknown lclTypeSpec kind: %d",
1738 return cstring_undefined
;
1741 /*@only@*/ enumSpecNode
1742 makeEnumSpecNode (ltoken t
, ltoken optTagId
,
1743 /*@owned@*/ ltokenList enums
)
1745 enumSpecNode n
= (enumSpecNode
) dmalloc (sizeof (*n
));
1747 smemberInfo
*top
= smemberInfo_undefined
;
1750 n
->opttagid
= ltoken_copy (optTagId
);
1753 /* generate sort for this LCL type */
1754 n
->sort
= sort_makeEnum (optTagId
);
1756 if (!ltoken_isUndefined (optTagId
))
1758 /* First, check to see if tag is already defined */
1759 ti
= symtable_tagInfo (g_symtab
, ltoken_getText (optTagId
));
1761 if (tagInfo_exists (ti
))
1763 if (ti
->kind
== TAG_ENUM
)
1765 /* 23 Sep 1995 --- had been noting here...is this right? */
1767 ti
->content
.enums
= enums
;
1769 ti
->imported
= context_inImport ();
1774 message ("Tag %s previously defined as %q, redefined as enum",
1775 ltoken_getRawString (optTagId
),
1776 tagKind_unparse (ti
->kind
)));
1778 /* evs --- shouldn't they be in different name spaces? */
1781 ltoken_free (optTagId
);
1785 ti
= (tagInfo
) dmalloc (sizeof (*ti
));
1787 ti
->kind
= TAG_ENUM
;
1789 ti
->content
.enums
= enums
;
1791 ti
->imported
= context_inImport ();
1792 /* First, store tag info in symbol table */
1793 (void) symtable_enterTag (g_symtab
, ti
);
1797 /* check that enumeration constants are unique */
1799 ltokenList_reset (enums
);
1801 while (!ltokenList_isFinished (enums
))
1803 ltoken c
= ltokenList_current (enums
);
1804 smemberInfo
*ei
= (smemberInfo
*) dmalloc (sizeof (*ei
));
1806 ei
->name
= ltoken_getText (c
);
1811 if (!varInfo_exists (symtable_varInfo (g_symtab
, ltoken_getText (c
))))
1812 { /* put info into symbol table */
1813 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
1815 vi
->id
= ltoken_copy (c
);
1816 vi
->kind
= VRK_ENUM
;
1820 (void) symtable_enterVar (g_symtab
, vi
);
1825 lclerror (c
, message ("Enumerated value redeclared: %s",
1826 ltoken_getRawString (c
)));
1827 ltokenList_removeCurrent (enums
);
1829 ltokenList_advance (enums
);
1834 (void) sort_updateEnum (n
->sort
, top
);
1838 /*@only@*/ enumSpecNode
1839 makeEnumSpecNode2 (ltoken t
, ltoken tagid
)
1841 /* a reference, not a definition */
1842 enumSpecNode n
= (enumSpecNode
) dmalloc (sizeof (*n
));
1843 tagInfo ti
= symtable_tagInfo (g_symtab
, ltoken_getText (tagid
));
1846 n
->opttagid
= tagid
;
1847 n
->enums
= ltokenList_new ();
1849 if (tagInfo_exists (ti
))
1851 if (ti
->kind
== TAG_ENUM
)
1857 n
->sort
= sort_makeNoSort ();
1858 lclerror (tagid
, message ("Tag %s defined as %q, used as enum",
1859 ltoken_getRawString (tagid
),
1860 tagKind_unparse (ti
->kind
)));
1865 n
->sort
= sort_makeNoSort ();
1866 lclerror (t
, message ("Undefined type: enum %s",
1867 ltoken_getRawString (tagid
)));
1873 static /*@only@*/ cstring
1874 enumSpecNode_unparse (/*@null@*/ enumSpecNode n
)
1876 if (n
!= (enumSpecNode
) 0)
1878 cstring s
= cstring_makeLiteral ("enum ");
1880 if (!ltoken_isUndefined (n
->opttagid
))
1882 s
= message ("%q%s ", s
, ltoken_getRawString (n
->opttagid
));
1885 s
= message ("%q{%q}", s
, printLeaves2 (n
->enums
));
1888 return cstring_undefined
;
1891 /*@only@*/ strOrUnionNode
1892 makestrOrUnionNode (ltoken str
, suKind k
, ltoken opttagid
,
1893 /*@only@*/ stDeclNodeList x
)
1895 strOrUnionNode n
= (strOrUnionNode
) dmalloc (sizeof (*n
));
1896 lsymbolSet set
= lsymbolSet_new ();
1897 declaratorNodeList declarators
;
1898 sort fieldsort
, tsort1
, tsort2
;
1899 smemberInfo
*mi
, *top
= smemberInfo_undefined
;
1901 bool isStruct
= (k
== SU_STRUCT
);
1907 n
->opttagid
= ltoken_copy (opttagid
);
1909 n
->sort
= isStruct
? sort_makeStr (opttagid
) : sort_makeUnion (opttagid
);
1911 if (!ltoken_isUndefined (opttagid
))
1913 /* First, check to see if tag is already defined */
1914 t
= symtable_tagInfo (g_symtab
, ltoken_getText (opttagid
));
1916 if (tagInfo_exists (t
))
1918 if ((t
->kind
== TAG_FWDUNION
&& k
== SU_UNION
) ||
1919 (t
->kind
== TAG_FWDSTRUCT
&& k
== SU_STRUCT
))
1921 /* to allow self-recursive types and forward tag declarations */
1922 t
->content
.decls
= stDeclNodeList_copy (x
); /* update tag info */
1928 message ("Tag %s previously defined as %q, used as %q",
1929 ltoken_getRawString (opttagid
),
1930 tagKind_unparse (t
->kind
),
1931 cstring_makeLiteral (isStruct
? "struct" : "union")));
1944 if (doTag
&& !ltoken_isUndefined (opttagid
))
1946 t
= (tagInfo
) dmalloc (sizeof (*t
));
1948 /* can either override prev defn or use prev defn */
1949 /* override it so as to detect more errors */
1951 t
->kind
= (k
== SU_STRUCT
) ? TAG_STRUCT
: TAG_UNION
;
1953 t
->content
.decls
= stDeclNodeList_copy (x
);
1955 t
->imported
= FALSE
;
1957 /* Next, update tag info in symbol table */
1958 (void) symtable_enterTagForce (g_symtab
, t
);
1961 /* check no duplicate field names */
1963 stDeclNodeList_elements (x
, i
)
1965 fieldsort
= lclTypeSpecNode2sort (i
->lcltypespec
);
1967 /* need the locations, not values */
1968 /* fieldsort = sort_makeObj (fieldsort); */
1970 fieldsort = sort_makeGlobal (fieldsort); */
1972 declarators
= i
->declarators
;
1974 declaratorNodeList_elements (declarators
, decl
)
1977 mi
= (smemberInfo
*) dmalloc (sizeof (*mi
));
1978 /* need to make dynamic copies */
1979 fieldname
= ltoken_getText (decl
->id
);
1981 /* 2/19/93, added */
1982 tsort1
= typeExpr2ptrSort (fieldsort
, decl
->type
);
1983 tsort2
= sort_makeGlobal (tsort1
);
1985 mi
->name
= fieldname
;
1986 mi
->sort
= tsort2
; /* fieldsort; */
1990 if (lsymbolSet_member (set
, fieldname
))
1993 message ("Field name reused: %s",
1994 ltoken_getRawString (decl
->id
)));
1998 (void) lsymbolSet_insert (set
, fieldname
);
2001 } end_declaratorNodeList_elements
;
2003 } end_stDeclNodeList_elements
;
2007 (void) sort_updateStr (n
->sort
, top
);
2011 (void) sort_updateUnion (n
->sort
, top
);
2014 /* We shall keep the info with both tags and types if any
2015 of them are present. */
2017 lsymbolSet_free (set
);
2022 /*@only@*/ strOrUnionNode
2023 makeForwardstrOrUnionNode (ltoken str
, suKind k
,
2026 strOrUnionNode n
= (strOrUnionNode
) dmalloc (sizeof (*n
));
2030 /* a reference, not a definition */
2034 n
->opttagid
= tagid
;
2035 n
->structdecls
= stDeclNodeList_new ();
2037 /* get sort for this LCL type */
2038 t
= symtable_tagInfo (g_symtab
, ltoken_getText (tagid
));
2040 if (tagInfo_exists (t
))
2044 if (!(((t
->kind
== TAG_STRUCT
|| t
->kind
== TAG_FWDSTRUCT
) && k
== SU_STRUCT
)
2045 || ((t
->kind
== TAG_UNION
|| t
->kind
== TAG_FWDUNION
) && k
== SU_UNION
)))
2048 message ("Tag %s previously defined as %q, used as %q",
2049 ltoken_getRawString (tagid
),
2050 tagKind_unparse (t
->kind
),
2051 cstring_makeLiteral ((k
== SU_STRUCT
) ? "struct" : "union")));
2057 ** changed from error: 31 Mar 1994
2059 ** lclerror (str, message ("Undefined type: %s %s", s, ltoken_getRawString (tagid));
2063 /* forward struct's and union's are ok... */
2067 (void) checkAndEnterTag (TAG_FWDSTRUCT
, ltoken_copy (tagid
));
2068 lhForwardStruct (tagid
);
2069 sort
= sort_makeStr (tagid
);
2073 (void) checkAndEnterTag (TAG_FWDUNION
, ltoken_copy (tagid
));
2074 lhForwardUnion (tagid
);
2075 sort
= sort_makeUnion (tagid
);
2083 static /*@only@*/ cstring
2084 strOrUnionNode_unparse (/*@null@*/ strOrUnionNode n
)
2086 if (n
!= (strOrUnionNode
) 0)
2092 s
= cstring_makeLiteral ("struct ");
2095 s
= cstring_makeLiteral ("union ");
2100 if (!ltoken_isUndefined (n
->opttagid
))
2102 s
= message ("%q%s ", s
, ltoken_getRawString (n
->opttagid
));
2104 s
= message ("%q{%q}", s
, stDeclNodeList_unparse (n
->structdecls
));
2107 return cstring_undefined
;
2110 /*@only@*/ stDeclNode
2111 makestDeclNode (lclTypeSpecNode s
,
2112 declaratorNodeList x
)
2114 stDeclNode n
= (stDeclNode
) dmalloc (sizeof (*n
));
2122 makeFunctionNode (typeExpr x
, paramNodeList p
)
2124 typeExpr y
= (typeExpr
) dmalloc (sizeof (*y
));
2127 y
->kind
= TEXPR_FCN
;
2128 y
->content
.function
.returntype
= x
;
2129 y
->content
.function
.args
= p
;
2130 y
->sort
= sort_makeNoSort ();
2135 static /*@observer@*/ ltoken
2136 extractDeclarator (/*@null@*/ typeExpr t
)
2138 if (t
!= (typeExpr
) 0)
2143 return t
->content
.base
;
2145 return (extractDeclarator (t
->content
.pointer
));
2147 return (extractDeclarator (t
->content
.array
.elementtype
));
2149 return (extractDeclarator (t
->content
.function
.returntype
));
2153 return ltoken_undefined
;
2157 makeTypeExpr (ltoken t
)
2159 typeExpr x
= (typeExpr
) dmalloc (sizeof (*x
));
2163 x
->kind
= TEXPR_BASE
;
2164 x
->content
.base
= t
;
2165 x
->sort
= sort_makeNoSort ();
2171 /*@only@*/ declaratorNode
2172 makeDeclaratorNode (typeExpr t
)
2174 declaratorNode x
= (declaratorNode
) dmalloc (sizeof (*x
));
2176 x
->id
= ltoken_copy (extractDeclarator (t
));
2178 x
->isRedecl
= FALSE
;
2183 static /*@only@*/ declaratorNode
2184 makeUnknownDeclaratorNode (/*@only@*/ ltoken t
)
2186 declaratorNode x
= (declaratorNode
) dmalloc (sizeof (*x
));
2189 x
->type
= (typeExpr
) 0;
2190 x
->isRedecl
= FALSE
;
2196 static /*@only@*/ cstring
2197 printTypeExpr2 (/*@null@*/ typeExpr x
)
2199 paramNodeList params
;
2201 if (x
!= (typeExpr
) 0)
2203 cstring s
; /* print out types in reverse order */
2208 return (message ("%s ", ltoken_getRawString (x
->content
.base
)));
2210 return (message ("%qptr to ", printTypeExpr2 (x
->content
.pointer
)));
2212 return (message ("array[%q] of %q",
2213 termNode_unparse (x
->content
.array
.size
),
2214 printTypeExpr2 (x
->content
.array
.elementtype
)));
2216 s
= printTypeExpr2 (x
->content
.function
.returntype
);
2217 params
= x
->content
.function
.args
;
2218 if (!paramNodeList_empty (params
))
2220 s
= message ("%qfcn with args: (%q)", s
,
2221 paramNodeList_unparse (x
->content
.function
.args
));
2224 s
= message ("%qfcn with no args", s
);
2227 llfatalbug (message ("printTypeExpr2: unknown typeExprKind: %d", (int) x
->kind
));
2230 return cstring_undefined
;
2235 declaratorNode_unparse (declaratorNode x
)
2237 return (typeExpr_unparse (x
->type
));
2240 /*@only@*/ declaratorNode
2241 declaratorNode_copy (declaratorNode x
)
2243 declaratorNode ret
= (declaratorNode
) dmalloc (sizeof (*ret
));
2245 ret
->type
= typeExpr_copy (x
->type
);
2246 ret
->id
= ltoken_copy (x
->id
);
2247 ret
->isRedecl
= x
->isRedecl
;
2252 static /*@null@*/ typeExpr
typeExpr_copy (/*@null@*/ typeExpr x
)
2260 typeExpr ret
= (typeExpr
) dmalloc (sizeof (*ret
));
2262 ret
->wrapped
= x
->wrapped
;
2263 ret
->kind
= x
->kind
;
2268 ret
->content
.base
= ltoken_copy (x
->content
.base
);
2271 ret
->content
.pointer
= typeExpr_copy (x
->content
.pointer
);
2274 ret
->content
.array
.elementtype
= typeExpr_copy (x
->content
.array
.elementtype
);
2275 ret
->content
.array
.size
= termNode_copy (x
->content
.array
.size
);
2278 ret
->content
.function
.returntype
= typeExpr_copy (x
->content
.function
.returntype
);
2279 ret
->content
.function
.args
= paramNodeList_copy (x
->content
.function
.args
);
2283 ret
->sort
= x
->sort
;
2288 static /*@only@*/ cstring
2289 typeExpr_unparseCode (/*@null@*/ typeExpr x
)
2291 /* print out types in order of appearance in source */
2292 cstring s
= cstring_undefined
;
2294 if (x
!= (typeExpr
) 0)
2299 return (cstring_copy (ltoken_getRawString (x
->content
.base
)));
2301 return (typeExpr_unparseCode (x
->content
.pointer
));
2303 return (typeExpr_unparseCode (x
->content
.array
.elementtype
));
2305 return (typeExpr_unparseCode (x
->content
.function
.returntype
));
2311 static void typeExpr_free (/*@only@*/ /*@null@*/ typeExpr x
)
2313 if (x
!= (typeExpr
) 0)
2320 typeExpr_free (x
->content
.pointer
);
2323 typeExpr_free (x
->content
.array
.elementtype
);
2324 termNode_free (x
->content
.array
.size
);
2327 typeExpr_free (x
->content
.function
.returntype
);
2328 paramNodeList_free (x
->content
.function
.args
);
2340 declaratorNode_unparseCode (declaratorNode x
)
2342 return (typeExpr_unparseCode (x
->type
));
2346 typeExpr_unparse (/*@null@*/ typeExpr x
)
2348 cstring s
= cstring_undefined
; /* print out types in order of appearance in source */
2349 paramNodeList params
;
2352 if (x
!= (typeExpr
) 0)
2354 cstring front
= cstring_undefined
;
2355 cstring back
= cstring_undefined
;
2357 llassert (x
->wrapped
< 100);
2359 for (i
= x
->wrapped
; i
>= 1; i
--)
2361 front
= cstring_appendChar (front
, '(');
2362 back
= cstring_appendChar (back
, ')');
2368 s
= message ("%q%s", s
, ltoken_getRawString (x
->content
.base
));
2371 s
= message ("%q*%q", s
, typeExpr_unparse (x
->content
.pointer
));
2374 s
= message ("%q%q[%q]", s
,
2375 typeExpr_unparse (x
->content
.array
.elementtype
),
2376 termNode_unparse (x
->content
.array
.size
));
2379 s
= message ("%q%q (", s
,
2380 typeExpr_unparse (x
->content
.function
.returntype
));
2381 params
= x
->content
.function
.args
;
2383 if (!paramNodeList_empty (params
))
2385 s
= message ("%q%q", s
,
2386 paramNodeList_unparse (x
->content
.function
.args
));
2389 s
= message ("%q)", s
);
2392 s
= message ("%q%q%q", front
, s
, back
);
2396 s
= cstring_makeLiteral ("?");
2402 static /*@only@*/ cstring
2403 typeExpr_unparseNoBase (/*@null@*/ typeExpr x
)
2405 cstring s
= cstring_undefined
; /* print out types in order of appearance in source */
2406 paramNodeList params
;
2409 if (x
!= (typeExpr
) 0)
2411 cstring front
= cstring_undefined
;
2412 cstring back
= cstring_undefined
;
2414 llassert (x
->wrapped
< 100);
2416 for (i
= x
->wrapped
; i
>= 1; i
--)
2418 front
= cstring_appendChar (front
, '(');
2419 back
= cstring_appendChar (back
, ')');
2425 s
= message ("%q /* %s */", s
, ltoken_getRawString (x
->content
.base
));
2428 s
= message ("%q*%q", s
, typeExpr_unparseNoBase (x
->content
.pointer
));
2431 s
= message ("%q%q[%q]", s
,
2432 typeExpr_unparseNoBase (x
->content
.array
.elementtype
),
2433 termNode_unparse (x
->content
.array
.size
));
2436 s
= message ("%q%q (", s
,
2437 typeExpr_unparseNoBase (x
->content
.function
.returntype
));
2438 params
= x
->content
.function
.args
;
2440 if (!paramNodeList_empty (params
))
2442 s
= message ("%q%q", s
,
2443 paramNodeList_unparse (x
->content
.function
.args
));
2446 s
= message ("%q)", s
);
2449 s
= message ("%q%q%q", front
, s
, back
);
2453 s
= cstring_makeLiteral ("?");
2460 typeExpr_name (/*@null@*/ typeExpr x
)
2462 if (x
!= (typeExpr
) 0)
2467 return (cstring_copy (ltoken_getRawString (x
->content
.base
)));
2469 return (typeExpr_name (x
->content
.pointer
));
2471 return (typeExpr_name (x
->content
.array
.elementtype
));
2473 return (typeExpr_name (x
->content
.function
.returntype
));
2477 /* evs --- 14 Mar 1995
2478 ** not a bug: its okay to have empty parameter names
2479 ** llbug ("typeExpr_name: null");
2482 return cstring_undefined
;
2486 makePointerNode (ltoken star
, /*@only@*/ /*@returned@*/ typeExpr x
)
2488 if (x
!= (typeExpr
)0 && (x
->kind
== TEXPR_FCN
&& (x
->wrapped
== 0)))
2490 x
->content
.function
.returntype
= makePointerNode (star
, x
->content
.function
.returntype
);
2495 typeExpr y
= (typeExpr
) dmalloc (sizeof (*y
));
2498 y
->kind
= TEXPR_PTR
;
2499 y
->content
.pointer
= x
;
2500 y
->sort
= sort_makeNoSort ();
2507 typeExpr
makeArrayNode (/*@returned@*/ typeExpr x
,
2508 /*@only@*/ arrayQualNode a
)
2510 if (x
!= (typeExpr
)0 && (x
->kind
== TEXPR_FCN
&& (x
->wrapped
== 0)))
2513 ** Spurious errors reported here, because of referencing
2514 ** in makeArrayNode.
2518 x
->content
.function
.returntype
= makeArrayNode (x
, a
);
2526 typeExpr y
= (typeExpr
) dmalloc (sizeof (*y
));
2528 y
->kind
= TEXPR_ARRAY
;
2530 if (a
== (arrayQualNode
) 0)
2532 y
->content
.array
.size
= (termNode
) 0;
2536 y
->content
.array
.size
= a
->term
;
2537 ltoken_free (a
->tok
);
2541 y
->content
.array
.elementtype
= x
;
2542 y
->sort
= sort_makeNoSort ();
2548 /*@only@*/ constDeclarationNode
2549 makeConstDeclarationNode (lclTypeSpecNode t
, initDeclNodeList decls
)
2551 constDeclarationNode n
= (constDeclarationNode
) dmalloc (sizeof (*n
));
2552 sort s
, s2
, initValueSort
;
2553 ltoken varid
, errtok
;
2556 s
= lclTypeSpecNode2sort (t
);
2558 initDeclNodeList_elements (decls
, init
)
2560 declaratorNode vdnode
= init
->declarator
;
2561 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
2563 varid
= ltoken_copy (vdnode
->id
);
2564 s2
= typeExpr2ptrSort (s
, vdnode
->type
);
2565 initValue
= init
->value
;
2567 if (termNode_isDefined (initValue
) && !initValue
->error_reported
)
2569 initValueSort
= initValue
->sort
;
2571 /* should keep the arguments in order */
2572 if (!sort_member_modulo_cstring (s2
, initValue
)
2573 && !initValue
->error_reported
)
2575 errtok
= termNode_errorToken (initValue
);
2579 message ("Constant %s declared type %q, initialized to %q: %q",
2580 ltoken_unparse (varid
),
2582 sort_unparse (initValueSort
),
2583 termNode_unparse (initValue
)));
2588 vi
->kind
= VRK_CONST
;
2592 (void) symtable_enterVar (g_symtab
, vi
);
2595 } end_initDeclNodeList_elements
;
2603 varDeclarationNode
makeInternalStateNode (void)
2605 varDeclarationNode n
= (varDeclarationNode
) dmalloc (sizeof (*n
));
2607 n
->isSpecial
= TRUE
;
2608 n
->sref
= sRef_makeInternalState ();
2610 /*@-compdef@*/ return n
; /*@=compdef@*/
2613 varDeclarationNode
makeFileSystemNode (void)
2615 varDeclarationNode n
= (varDeclarationNode
) dmalloc (sizeof (*n
));
2617 n
->isSpecial
= TRUE
;
2618 n
->sref
= sRef_makeSystemState ();
2620 /*@-compdef@*/ return n
; /*@=compdef@*/
2623 /*@only@*/ varDeclarationNode
2624 makeVarDeclarationNode (lclTypeSpecNode t
, initDeclNodeList x
,
2625 bool isGlobal
, bool isPrivate
)
2627 varDeclarationNode n
= (varDeclarationNode
) dmalloc (sizeof (*n
));
2628 sort s
, s2
, initValueSort
;
2629 ltoken varid
, errtok
;
2631 declaratorNode vdnode
;
2633 n
->isSpecial
= FALSE
;
2634 n
->qualifier
= QLF_NONE
;
2635 n
->isGlobal
= isGlobal
;
2636 n
->isPrivate
= isPrivate
;
2639 s
= lclTypeSpecNode2sort (t
);
2641 /* t is an lclTypeSpec, its sort may not be assigned yet */
2643 initDeclNodeList_elements (x
, init
)
2645 vdnode
= init
->declarator
;
2647 s2
= typeExpr2ptrSort (s
, vdnode
->type
);
2648 initValue
= init
->value
;
2650 if (termNode_isDefined (initValue
) && !initValue
->error_reported
)
2652 initValueSort
= initValue
->sort
;
2653 /* should keep the arguments in order */
2654 if (!sort_member_modulo_cstring (s2
, initValue
)
2655 && !initValue
->error_reported
)
2657 errtok
= termNode_errorToken (initValue
);
2660 message ("Variable %s declared type %q, initialized to %q",
2661 ltoken_unparse (varid
),
2663 sort_unparse (initValueSort
)));
2668 ** If global, check that it has been declared already, don't push
2669 ** onto symbol table yet (wrong scope, done in enteringFcnScope
2674 varInfo vi
= symtable_varInfo (g_symtab
, ltoken_getText (varid
));
2676 if (!varInfo_exists (vi
))
2679 message ("Undeclared global variable: %s",
2680 ltoken_getRawString (varid
)));
2684 if (vi
->kind
== VRK_CONST
)
2687 message ("Constant used in global list: %s",
2688 ltoken_getRawString (varid
)));
2694 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
2696 vi
->id
= ltoken_copy (varid
);
2699 vi
->kind
= VRK_PRIVATE
;
2700 /* check that initValue is not empty */
2701 if (initValue
== (termNode
) 0)
2704 message ("Private variable must have initialization: %s",
2705 ltoken_getRawString (varid
)));
2713 vi
->sort
= sort_makeGlobal (s2
);
2716 vdnode
->isRedecl
= symtable_enterVar (g_symtab
, vi
);
2719 } end_initDeclNodeList_elements
;
2726 /*@only@*/ initDeclNode
2727 makeInitDeclNode (declaratorNode d
, termNode x
)
2729 initDeclNode n
= (initDeclNode
) dmalloc (sizeof (*n
));
2736 /*@only@*/ abstractNode
2737 makeAbstractNode (ltoken t
, ltoken name
,
2738 bool isMutable
, bool isRefCounted
, abstBodyNode a
)
2740 abstractNode n
= (abstractNode
) dmalloc (sizeof (*n
));
2742 typeInfo ti
= (typeInfo
) dmalloc (sizeof (*ti
));
2745 n
->isMutable
= isMutable
;
2748 n
->isRefCounted
= isRefCounted
;
2751 handle
= sort_makeMutable (name
, ltoken_getText (name
));
2753 handle
= sort_makeImmutable (name
, ltoken_getText (name
));
2756 ti
->id
= ltoken_createType (ltoken_getCode (ltoken_typename
), SID_TYPE
,
2757 ltoken_getText (name
));
2758 ti
->modifiable
= isMutable
;
2759 ti
->abstract
= TRUE
;
2760 ti
->basedOn
= handle
;
2763 symtable_enterType (g_symtab
, ti
);
2771 abstractNode_unparse (abstractNode n
)
2773 if (n
!= (abstractNode
) 0)
2778 s
= cstring_makeLiteral ("mutable");
2780 s
= cstring_makeLiteral ("immutable");
2782 return (message ("%q type %s%q;", s
, ltoken_getRawString (n
->name
),
2783 abstBodyNode_unparse (n
->body
)));
2785 return cstring_undefined
;
2787 # endif /* DEADCODE */
2790 setExposedType (lclTypeSpecNode s
)
2795 /*@only@*/ exposedNode
2796 makeExposedNode (ltoken t
, lclTypeSpecNode s
,
2797 declaratorInvNodeList d
)
2799 exposedNode n
= (exposedNode
) dmalloc (sizeof (*n
));
2810 exposedNode_unparse (exposedNode n
)
2812 if (n
!= (exposedNode
) 0)
2814 return (message ("typedef %q %q;",
2815 lclTypeSpecNode_unparse (n
->type
),
2816 declaratorInvNodeList_unparse (n
->decls
)));
2818 return cstring_undefined
;
2820 # endif /* DEADCODE */
2822 /*@only@*/ declaratorInvNode
2823 makeDeclaratorInvNode (declaratorNode d
, abstBodyNode b
)
2825 declaratorInvNode n
= (declaratorInvNode
) dmalloc (sizeof (*n
));
2834 declaratorInvNode_unparse (declaratorInvNode d
)
2836 return (message ("%q%q", declaratorNode_unparse (d
->declarator
),
2837 abstBodyNode_unparseExposed (d
->body
)));
2841 abstBodyNode_unparse (abstBodyNode n
)
2843 if (n
!= (abstBodyNode
) 0)
2845 return (lclPredicateNode_unparse (n
->typeinv
));
2847 return cstring_undefined
;
2851 abstBodyNode_unparseExposed (abstBodyNode n
)
2853 if (n
!= (abstBodyNode
) 0)
2855 return (message ("%q", lclPredicateNode_unparse (n
->typeinv
)));
2857 return cstring_undefined
;
2861 taggedUnionNode_unparse (taggedUnionNode n
)
2863 if (n
!= (taggedUnionNode
) 0)
2865 return (message ("tagged union {%q}%q;\n",
2866 stDeclNodeList_unparse (n
->structdecls
),
2867 declaratorNode_unparse (n
->declarator
)));
2869 return cstring_undefined
;
2871 # endif /* DEADCODE */
2873 static /*@observer@*/ paramNodeList
2874 typeExpr_toParamNodeList (/*@null@*/ typeExpr te
)
2876 if (te
!= (typeExpr
) 0)
2881 return te
->content
.function
.args
;
2883 return typeExpr_toParamNodeList (te
->content
.pointer
);
2885 /* return typeExpr_toParamNodeList (te->content.array.elementtype); */
2887 return paramNodeList_undefined
;
2890 return paramNodeList_undefined
;
2894 fcnNode_fromDeclarator (/*@only@*/ /*@null@*/ lclTypeSpecNode t
,
2895 /*@only@*/ declaratorNode d
)
2897 return (makeFcnNode (qual_createUnknown (), t
, d
,
2898 varDeclarationNodeList_new (),
2899 varDeclarationNodeList_new (),
2900 letDeclNodeList_new (),
2901 (lclPredicateNode
) 0,
2902 (lclPredicateNode
) 0,
2904 (lclPredicateNode
) 0,
2905 (lclPredicateNode
) 0));
2909 makeIterNode (ltoken id
, paramNodeList p
)
2911 iterNode x
= (iterNode
) dmalloc (sizeof (*x
));
2912 bool hasYield
= FALSE
;
2917 /* check there is at least one yield param */
2919 paramNodeList_elements (p
, pe
)
2921 if (paramNode_isYield (pe
))
2926 } end_paramNodeList_elements
2930 lclerror (id
, message ("Iterator has no yield parameters: %s",
2931 ltoken_getRawString (id
)));
2938 makeFcnNode (qual specQual
,
2939 /*@null@*/ lclTypeSpecNode t
,
2941 /*@null@*/ globalList g
,
2942 /*@null@*/ varDeclarationNodeList privateinits
,
2943 /*@null@*/ letDeclNodeList lets
,
2944 /*@null@*/ lclPredicateNode checks
,
2945 /*@null@*/ lclPredicateNode requires
,
2946 /*@null@*/ modifyNode m
,
2947 /*@null@*/ lclPredicateNode ensures
,
2948 /*@null@*/ lclPredicateNode claims
)
2950 fcnNode x
= (fcnNode
) dmalloc (sizeof (*x
));
2952 if (d
->type
!= (typeExpr
)0 && (d
->type
)->kind
!= TEXPR_FCN
)
2954 lclerror (d
->id
, cstring_makeLiteral
2955 ("Attempt to specify function without parameter list"));
2956 d
->type
= makeFunctionNode (d
->type
, paramNodeList_new ());
2959 x
->special
= specQual
;
2963 x
->inits
= privateinits
;
2966 x
->require
= requires
;
2968 x
->ensures
= ensures
;
2971 /* extract info to fill in x->name =; x->signature =; */
2972 x
->name
= ltoken_copy (d
->id
);
2977 /*@only@*/ claimNode
2978 makeClaimNode (ltoken id
, paramNodeList p
,
2979 globalList g
, letDeclNodeList lets
, lclPredicateNode requires
,
2980 programNode b
, lclPredicateNode ensures
)
2982 claimNode x
= (claimNode
) dmalloc (sizeof (*x
));
2989 x
->require
= requires
;
2991 x
->ensures
= ensures
;
2995 /*@only@*/ lclPredicateNode
2996 makeIntraClaimNode (ltoken t
, lclPredicateNode n
)
2998 ltoken_free (n
->tok
);
3000 n
->kind
= LPD_INTRACLAIM
;
3004 /*@only@*/ lclPredicateNode
3005 makeRequiresNode (ltoken t
, lclPredicateNode n
)
3007 ltoken_free (n
->tok
);
3009 n
->kind
= LPD_REQUIRES
;
3013 /*@only@*/ lclPredicateNode
3014 makeChecksNode (ltoken t
, lclPredicateNode n
)
3016 ltoken_free (n
->tok
);
3018 n
->kind
= LPD_CHECKS
;
3022 /*@only@*/ lclPredicateNode
3023 makeEnsuresNode (ltoken t
, lclPredicateNode n
)
3025 ltoken_free (n
->tok
);
3027 n
->kind
= LPD_ENSURES
;
3031 /*@only@*/ lclPredicateNode
3032 makeLclPredicateNode (ltoken t
, termNode n
,
3035 lclPredicateNode x
= (lclPredicateNode
) dmalloc (sizeof (*x
));
3043 /*@only@*/ quantifierNode
3044 makeQuantifierNode (varNodeList v
, ltoken quant
)
3046 quantifierNode x
= (quantifierNode
) dmalloc (sizeof (*x
));
3050 x
->isForall
= cstring_equalLit (ltoken_unparse (quant
), "\forall");
3055 /*@only@*/ arrayQualNode
3056 makeArrayQualNode (ltoken t
, termNode term
)
3058 arrayQualNode x
= (arrayQualNode
) dmalloc (sizeof (*x
));
3066 makeVarNode (/*@only@*/ ltoken varid
, bool isObj
, lclTypeSpecNode t
)
3068 varNode x
= (varNode
) dmalloc (sizeof (*x
));
3069 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
3072 vi
->id
= ltoken_copy (varid
);
3073 sort
= lclTypeSpecNode2sort (t
);
3075 /* 9/3/93, The following is needed because we want value sorts to be
3076 the default, object sort is generated only if there is "obj" qualifier.
3077 There are 2 cases: (1) for immutable types (including C primitive types),
3078 we need to generate the object sort if qualifier is present; (2) for
3079 array, struct and union types, they are already in their object sorts.
3082 sort
= sort_makeVal (sort
); /* both cases are now value sorts */
3086 sort
= sort_makeObj (sort
);
3091 vi
->kind
= VRK_QUANT
;
3094 (void) symtable_enterVar (g_symtab
, vi
);
3100 x
->sort
= sort_makeNoSort ();
3105 /*@only@*/ abstBodyNode
3106 makeAbstBodyNode (ltoken t
, fcnNodeList f
)
3108 abstBodyNode x
= (abstBodyNode
) dmalloc (sizeof (*x
));
3111 x
->typeinv
= (lclPredicateNode
)0;
3116 /*@only@*/ abstBodyNode
3117 makeExposedBodyNode (ltoken t
, lclPredicateNode inv
)
3119 abstBodyNode x
= (abstBodyNode
) dmalloc (sizeof (*x
));
3123 x
->fcns
= fcnNodeList_undefined
;
3127 /*@only@*/ abstBodyNode
3128 makeAbstBodyNode2 (ltoken t
, ltokenList ops
)
3130 abstBodyNode x
= (abstBodyNode
) dmalloc (sizeof (*x
));
3133 x
->typeinv
= (lclPredicateNode
) 0;
3135 x
->fcns
= fcnNodeList_new ();
3137 ltokenList_elements (ops
, op
)
3139 x
->fcns
= fcnNodeList_add
3141 fcnNode_fromDeclarator (lclTypeSpecNode_undefined
,
3142 makeUnknownDeclaratorNode (ltoken_copy (op
))));
3143 } end_ltokenList_elements
;
3145 ltokenList_free (ops
);
3151 makeStmtNode (ltoken varId
, ltoken fcnId
, /*@only@*/ termNodeList v
)
3153 stmtNode n
= (stmtNode
) dmalloc (sizeof (*n
));
3156 n
->operator = fcnId
;
3161 /* printDeclarators -> declaratorNodeList_unparse */
3163 static cstring
abstDeclaratorNode_unparse (abstDeclaratorNode x
)
3165 return (typeExpr_unparse ((typeExpr
) x
));
3168 /*@only@*/ paramNode
3169 makeParamNode (lclTypeSpecNode t
, typeExpr d
)
3171 paramNode x
= (paramNode
) dmalloc (sizeof (*x
));
3173 paramNode_checkQualifiers (t
, d
);
3177 x
->kind
= PNORMAL
; /*< forgot this! >*/
3182 /*@only@*/ paramNode
3183 paramNode_elipsis (void)
3185 paramNode x
= (paramNode
) dmalloc (sizeof (*x
));
3187 x
->type
= (lclTypeSpecNode
) 0;
3188 x
->paramdecl
= (typeExpr
) 0;
3194 static /*@observer@*/ ltoken
typeExpr_getTok (typeExpr d
)
3196 while (d
!= (typeExpr
)0)
3198 if (d
->kind
== TEXPR_BASE
)
3200 return (d
->content
.base
);
3204 if (d
->kind
== TEXPR_PTR
)
3206 d
= d
->content
.pointer
;
3208 else if (d
->kind
== TEXPR_ARRAY
)
3210 d
= d
->content
.array
.elementtype
;
3212 else if (d
->kind
== TEXPR_FCN
)
3214 d
= d
->content
.function
.returntype
;
3223 llfatalerror (cstring_makeLiteral ("typeExpr_getTok: unreachable code"));
3228 paramNode_checkQualifiers (lclTypeSpecNode t
, typeExpr d
)
3230 bool isPointer
= FALSE
;
3231 bool isUser
= FALSE
;
3232 bool hasAlloc
= FALSE
;
3233 bool hasAlias
= FALSE
;
3235 llassert (lclTypeSpecNode_isDefined (t
));
3237 if (pointers_isUndefined (t
->pointers
)
3238 && (d
!= (typeExpr
)0 && d
->kind
!= TEXPR_PTR
) && d
->kind
!= TEXPR_ARRAY
)
3240 if (t
->kind
== LTS_TYPE
)
3244 llassert (t
->content
.type
!= NULL
);
3246 sn
= sort_quietLookup (sort_getUnderlying ((t
->content
.type
)->sort
));
3248 if (sn
->kind
== SRT_PTR
|| sn
->kind
== SRT_ARRAY
3249 || sn
->kind
== SRT_HOF
|| sn
->kind
== SRT_NONE
)
3260 if (d
!= (typeExpr
)0 && d
->kind
!= TEXPR_BASE
)
3262 if (t
->kind
== LTS_TYPE
)
3266 llassert (t
->content
.type
!= NULL
);
3267 sn
= sort_quietLookup (sort_getUnderlying ((t
->content
.type
)->sort
));
3269 if (sn
->kind
== SRT_PTR
|| sn
->kind
== SRT_ARRAY
3270 || sn
->kind
== SRT_HOF
|| sn
->kind
== SRT_NONE
)
3281 if (d
!= (typeExpr
)NULL
)
3283 qualList_elements (t
->quals
, q
)
3285 if (qual_isAllocQual (q
))
3289 ltoken tok
= typeExpr_getTok (d
);
3290 lclerror (tok
, message ("Parameter declared with multiple allocation "
3291 "qualifiers: %q", typeExpr_unparse (d
)));
3297 ltoken tok
= typeExpr_getTok (d
);
3298 lclerror (tok
, message ("Non-pointer declared as %s parameter: %q",
3300 typeExpr_unparse (d
)));
3303 if (qual_isAliasQual (q
))
3307 ltoken tok
= typeExpr_getTok (d
);
3308 lclerror (tok
, message ("Parameter declared with multiple alias qualifiers: %q",
3309 typeExpr_unparse (d
)));
3313 if (!(isPointer
|| isUser
))
3315 ltoken tok
= typeExpr_getTok (d
);
3316 lclerror (tok
, message ("Unsharable type declared as %s parameter: %q",
3318 typeExpr_unparse (d
)));
3321 } end_qualList_elements
;
3326 paramNode_unparse (paramNode x
)
3328 if (x
!= (paramNode
) 0)
3330 if (x
->kind
== PELIPSIS
)
3332 return (cstring_makeLiteral ("..."));
3335 if (x
->paramdecl
!= (typeExpr
) 0)
3336 { /* handle (void) */
3337 return (message ("%q %q", lclTypeSpecNode_unparse (x
->type
),
3338 typeExpr_unparse (x
->paramdecl
)));
3342 return (lclTypeSpecNode_unparse (x
->type
));
3345 return cstring_undefined
;
3349 lclTypeSpecNode_unparseAltComments (/*@null@*/ lclTypeSpecNode typespec
) /*@*/
3351 if (typespec
!= (lclTypeSpecNode
) 0)
3353 cstring s
= qualList_toCComments (typespec
->quals
);
3355 switch (typespec
->kind
)
3359 llassert (typespec
->content
.type
!= NULL
);
3361 return (cstring_concatFree
3362 (s
, printLeaves (typespec
->content
.type
->ctypes
)));
3367 enumSpecNode n
= typespec
->content
.enumspec
;
3369 s
= cstring_concatFree (s
, cstring_makeLiteral ("enum"));
3370 llassert (n
!= NULL
);
3372 if (!ltoken_isUndefined (n
->opttagid
))
3374 s
= message ("%q %s", s
, ltoken_unparse (n
->opttagid
));
3376 s
= message ("%q {", s
);
3378 ltokenList_elements (n
->enums
, e
)
3383 s
= message ("%q%s", s
, ltoken_getRawString (e
));
3386 s
= message ("%q, %s", s
, ltoken_getRawString (e
));
3387 } end_ltokenList_elements
;
3389 return (message ("%q}", s
));
3391 case LTS_STRUCTUNION
:
3393 strOrUnionNode n
= typespec
->content
.structorunion
;
3394 stDeclNodeList decls
;
3396 llassert (n
!= NULL
);
3401 s
= cstring_concatFree (s
, cstring_makeLiteral ("struct "));
3402 /*@switchbreak@*/ break;
3404 s
= cstring_concatFree (s
, cstring_makeLiteral ("union "));
3405 /*@switchbreak@*/ break;
3408 if (!ltoken_isUndefined (n
->opttagid
))
3410 if (stDeclNodeList_size (n
->structdecls
) == 0)
3412 return (message ("%q%s", s
, ltoken_unparse (n
->opttagid
)));
3415 s
= message ("%q%s {\n\t", s
, ltoken_unparse (n
->opttagid
));
3419 s
= message ("%q{\n\t", s
);
3422 decls
= n
->structdecls
;
3424 stDeclNodeList_elements (decls
, f
)
3426 s
= message ("%q%q %q;\n\t", s
,
3427 lclTypeSpecNode_unparseAltComments (f
->lcltypespec
),
3428 declaratorNodeList_unparse (f
->declarators
));
3429 } end_stDeclNodeList_elements
;
3431 return (message ("%q }", s
));
3440 lclTypeSpecNode_unparseAltComments (typespec
->content
.conj
->a
),
3441 lclTypeSpecNode_unparseAltComments (typespec
->content
.conj
->b
)));
3448 llcontbuglit ("lclTypeSpecNode_unparseComments: null typespec");
3450 return cstring_undefined
;
3456 cstring
lclTypeSpecNode_unparseComments (/*@null@*/ lclTypeSpecNode typespec
)
3458 if (typespec
!= lclTypeSpecNode_undefined
)
3460 cstring s
= qualList_toCComments (typespec
->quals
);
3462 switch (typespec
->kind
)
3466 llassert (typespec
->content
.type
!= NULL
);
3468 return (cstring_concatFree
3469 (s
, printLeaves (typespec
->content
.type
->ctypes
)));
3474 enumSpecNode n
= typespec
->content
.enumspec
;
3476 s
= cstring_concatFree (s
, cstring_makeLiteral ("enum"));
3477 llassert (n
!= NULL
);
3479 if (!ltoken_isUndefined (n
->opttagid
))
3481 s
= message ("%q %s", s
, ltoken_unparse (n
->opttagid
));
3483 s
= message ("%q {", s
);
3485 ltokenList_elements (n
->enums
, e
)
3490 s
= message ("%q%s", s
, ltoken_getRawString (e
));
3493 s
= message ("%q, %s", s
, ltoken_getRawString (e
));
3494 } end_ltokenList_elements
;
3496 return (message ("%q}", s
));
3498 case LTS_STRUCTUNION
:
3500 strOrUnionNode n
= typespec
->content
.structorunion
;
3501 stDeclNodeList decls
;
3503 llassert (n
!= NULL
);
3508 s
= cstring_concatFree (s
, cstring_makeLiteral ("struct "));
3509 /*@switchbreak@*/ break;
3511 s
= cstring_concatFree (s
, cstring_makeLiteral ("union "));
3512 /*@switchbreak@*/ break;
3515 if (!ltoken_isUndefined (n
->opttagid
))
3517 if (stDeclNodeList_size (n
->structdecls
) == 0)
3519 return (message ("%q%s", s
, ltoken_unparse (n
->opttagid
)));
3522 s
= message ("%q%s {\n\t", s
, ltoken_unparse (n
->opttagid
));
3526 s
= message ("%q{\n\t", s
);
3529 decls
= n
->structdecls
;
3531 stDeclNodeList_elements (decls
, f
)
3533 s
= message ("%q%q %q;\n\t", s
,
3534 lclTypeSpecNode_unparseComments (f
->lcltypespec
),
3535 declaratorNodeList_unparse (f
->declarators
));
3536 } end_stDeclNodeList_elements
;
3538 return (message ("%q }", s
));
3547 lclTypeSpecNode_unparseComments (typespec
->content
.conj
->a
),
3548 lclTypeSpecNode_unparseAltComments (typespec
->content
.conj
->b
)));
3555 llcontbuglit ("lclTypeSpecNode_unparseComments: null typespec");
3557 return cstring_undefined
;
3564 paramNode_unparseComments (paramNode x
)
3566 if (x
!= (paramNode
) 0)
3568 if (x
->kind
== PELIPSIS
)
3570 return (cstring_makeLiteral ("..."));
3573 if (x
->paramdecl
!= (typeExpr
) 0)
3574 { /* handle (void) */
3575 return (message ("%q %q",
3576 lclTypeSpecNode_unparseComments (x
->type
),
3577 typeExpr_unparseNoBase (x
->paramdecl
)));
3581 return (lclTypeSpecNode_unparseComments (x
->type
));
3584 return cstring_undefined
;
3588 makeIfTermNode (ltoken ift
, termNode ifn
, ltoken thent
,
3589 termNode thenn
, ltoken elset
,
3592 termNode t
= (termNode
) dmalloc (sizeof (*t
));
3593 opFormNode opform
= makeOpFormNode (ift
, OPF_IF
, opFormUnion_createMiddle (0),
3595 nameNode nn
= makeNameNodeForm (opform
);
3596 termNodeList args
= termNodeList_new ();
3598 t
->error_reported
= FALSE
;
3600 termNodeList_addh (args
, ifn
);
3601 termNodeList_addh (args
, thenn
);
3602 termNodeList_addh (args
, elsen
);
3605 t
->kind
= TRM_APPLICATION
;
3606 t
->sort
= sort_makeNoSort ();
3608 t
->possibleSorts
= sortSet_new ();
3609 t
->possibleOps
= lslOpSet_new ();
3611 ltoken_free (thent
);
3612 ltoken_free (elset
);
3617 static /*@observer@*/ ltoken
3618 nameNode2anyOp (nameNode n
)
3620 if (n
!= (nameNode
) 0)
3622 opFormNode opnode
= n
->content
.opform
;
3625 llassert (opnode
!= NULL
);
3627 kind
= opnode
->kind
;
3629 if (kind
== OPF_MANYOPM
|| kind
== OPF_ANYOP
||
3630 kind
== OPF_MANYOP
|| kind
== OPF_ANYOPM
)
3634 u
= opnode
->content
;
3638 return ltoken_undefined
;
3642 makeInfixTermNode (termNode x
, ltoken op
, termNode y
)
3644 termNode t
= (termNode
) dmalloc (sizeof (*t
));
3647 termNodeList args
= termNodeList_new ();
3649 checkAssociativity (x
, op
);
3651 opform
= makeOpFormNode (op
, OPF_MANYOPM
,
3652 opFormUnion_createAnyOp (op
),
3655 nn
= makeNameNodeForm (opform
);
3657 t
->error_reported
= FALSE
;
3659 termNodeList_addh (args
, x
);
3660 termNodeList_addh (args
, y
);
3663 t
->kind
= TRM_APPLICATION
;
3664 t
->sort
= sort_makeNoSort ();
3666 t
->possibleSorts
= sortSet_new (); /* sort_equal */
3667 t
->possibleOps
= lslOpSet_new ();
3671 /*@only@*/ quantifiedTermNode
3672 quantifiedTermNode_copy (quantifiedTermNode q
)
3674 quantifiedTermNode ret
= (quantifiedTermNode
) dmalloc (sizeof (*ret
));
3676 ret
->quantifiers
= quantifierNodeList_copy (q
->quantifiers
);
3677 ret
->open
= ltoken_copy (q
->open
);
3678 ret
->close
= ltoken_copy (q
->close
);
3679 ret
->body
= termNode_copySafe (q
->body
);
3685 makeQuantifiedTermNode (quantifierNodeList qn
, ltoken open
,
3686 termNode t
, ltoken close
)
3689 termNode n
= (termNode
) dmalloc (sizeof (*n
));
3690 quantifiedTermNode q
= (quantifiedTermNode
) dmalloc (sizeof (*q
));
3692 n
->name
= NULL
; /*> missing this --- detected by splint <*/
3693 n
->error_reported
= FALSE
;
3695 n
->error_reported
= FALSE
;
3696 n
->kind
= TRM_QUANTIFIER
;
3697 n
->possibleSorts
= sortSet_new ();
3698 n
->possibleOps
= lslOpSet_new ();
3699 n
->kind
= TRM_UNCHANGEDALL
;
3700 n
->args
= termNodeList_new (); /*< forgot this >*/
3702 termNodeList_free (t
->args
);
3703 t
->args
= termNodeList_new ();
3707 (void) sortSet_insert (n
->possibleSorts
, sort
);
3709 q
->quantifiers
= qn
;
3719 makePostfixTermNode (/*@returned@*/ /*@only@*/ termNode secondary
, ltokenList postfixops
)
3721 termNode top
= secondary
;
3723 ltokenList_elements (postfixops
, op
)
3725 top
= makePostfixTermNode2 (top
, ltoken_copy (op
));
3726 /*@i@*/ } end_ltokenList_elements
;
3728 ltokenList_free (postfixops
);
3730 return (top
); /* dep as only? */
3734 ** secondary is returned in the args list
3738 makePostfixTermNode2 (/*@returned@*/ /*@only@*/ termNode secondary
,
3739 /*@only@*/ ltoken postfixop
)
3741 termNode t
= (termNode
) dmalloc (sizeof (*t
));
3743 opFormNode opform
= makeOpFormNode (postfixop
,
3744 OPF_MANYOP
, opFormUnion_createAnyOp (postfixop
),
3746 nameNode nn
= makeNameNodeForm (opform
);
3747 termNodeList args
= termNodeList_new ();
3749 t
->error_reported
= FALSE
;
3751 termNodeList_addh (args
, secondary
);
3754 t
->kind
= TRM_APPLICATION
;
3755 t
->sort
= sort_makeNoSort ();
3757 t
->possibleSorts
= sortSet_new ();
3758 t
->possibleOps
= lslOpSet_new ();
3763 makePrefixTermNode (ltoken op
, termNode arg
)
3765 termNode t
= (termNode
) dmalloc (sizeof (*t
));
3766 termNodeList args
= termNodeList_new ();
3767 opFormNode opform
= makeOpFormNode (op
, OPF_ANYOPM
, opFormUnion_createAnyOp (op
),
3769 nameNode nn
= makeNameNodeForm (opform
);
3771 t
->error_reported
= FALSE
;
3774 termNodeList_addh (args
, arg
);
3776 t
->kind
= TRM_APPLICATION
;
3777 t
->sort
= sort_makeNoSort ();
3779 t
->possibleSorts
= sortSet_new ();
3780 t
->possibleOps
= lslOpSet_new ();
3785 makeOpCallTermNode (ltoken op
, ltoken open
,
3786 termNodeList args
, ltoken close
)
3788 /* like prefixTerm, but with opId LPAR termNodeList RPAR */
3789 termNode t
= (termNode
) dmalloc (sizeof (*t
));
3790 nameNode nn
= makeNameNodeId (op
);
3792 t
->error_reported
= FALSE
;
3796 t
->kind
= TRM_APPLICATION
;
3797 t
->sort
= sort_makeNoSort ();
3799 t
->possibleSorts
= sortSet_new ();
3800 t
->possibleOps
= lslOpSet_new ();
3803 ltoken_free (close
);
3808 /*@exposed@*/ termNode
3809 CollapseInfixTermNode (/*@returned@*/ termNode secondary
, termNodeList infix
)
3811 termNode left
= secondary
;
3813 termNodeList_elements (infix
, node
)
3815 termNodeList_addl (node
->args
, termNode_copySafe (left
));
3817 /* computePossibleSorts (left); */
3818 } end_termNodeList_elements
;
3824 checkAssociativity (termNode x
, ltoken op
)
3828 if (x
->wrapped
== 0 && /* no parentheses */
3829 x
->kind
== TRM_APPLICATION
&& x
->name
!= (nameNode
) 0 &&
3832 lastOpToken
= nameNode2anyOp (x
->name
);
3834 if ((ltoken_getCode (lastOpToken
) == logicalOp
&&
3835 ltoken_getCode (op
) == logicalOp
) ||
3836 ((ltoken_getCode (lastOpToken
) == simpleOp
||
3837 ltoken_getCode (lastOpToken
) == LLT_MULOP
) &&
3838 (ltoken_getCode (op
) == simpleOp
||
3839 ltoken_getCode (op
) == LLT_MULOP
)))
3840 if (ltoken_getText (lastOpToken
) != ltoken_getText (op
))
3844 ("Parentheses needed to specify associativity of %s and %s",
3845 cstring_fromChars (lsymbol_toChars (ltoken_getText (lastOpToken
))),
3846 cstring_fromChars (lsymbol_toChars (ltoken_getText (op
)))));
3852 pushInfixOpPartNode (/*@returned@*/ termNodeList x
, ltoken op
,
3853 /*@only@*/ termNode secondary
)
3855 termNode lastLeftTerm
;
3856 termNodeList args
= termNodeList_new ();
3857 termNode t
= (termNode
) dmalloc (sizeof (*t
));
3861 termNodeList_addh (args
, secondary
);
3863 if (!termNodeList_empty (x
))
3865 termNodeList_reset (x
);
3866 lastLeftTerm
= termNodeList_current (x
);
3867 checkAssociativity (lastLeftTerm
, op
);
3870 opform
= makeOpFormNode (op
, OPF_MANYOPM
,
3871 opFormUnion_createAnyOp (op
), ltoken_undefined
);
3873 nn
= makeNameNodeForm (opform
);
3875 t
->error_reported
= FALSE
;
3878 t
->kind
= TRM_APPLICATION
;
3880 t
->sort
= sort_makeNoSort ();
3882 t
->possibleSorts
= sortSet_new ();
3883 t
->possibleOps
= lslOpSet_new ();
3884 termNodeList_addh (x
, t
);
3885 /* don't compute sort yet, do it in CollapseInfixTermNode */
3890 updateMatchedNode (/*@only@*/ termNode left
, /*@returned@*/ termNode t
,
3891 /*@only@*/ termNode right
)
3895 if ((t
== (termNode
) 0) || (t
->name
== NULL
) || t
->name
->isOpId
)
3897 llbugexitlit ("updateMatchedNode: expect opForm in nameNode");
3900 op
= t
->name
->content
.opform
;
3901 llassert (op
!= NULL
);
3903 if (left
== (termNode
) 0)
3905 if (right
== (termNode
) 0)
3907 /* op->kind is not changed */
3908 termNode_free (right
);
3912 op
->kind
= OPF_MIDDLEM
;
3913 op
->key
= opFormNode2key (op
, OPF_MIDDLEM
);
3914 termNodeList_addh (t
->args
, right
);
3919 termNodeList_addl (t
->args
, left
);
3920 if (right
== (termNode
) 0)
3922 op
->kind
= OPF_MMIDDLE
;
3923 op
->key
= opFormNode2key (op
, OPF_MMIDDLE
);
3927 op
->kind
= OPF_MMIDDLEM
;
3928 op
->key
= opFormNode2key (op
, OPF_MMIDDLEM
);
3929 termNodeList_addh (t
->args
, right
);
3936 updateSqBracketedNode (/*@only@*/ termNode left
,
3937 /*@only@*/ /*@returned@*/ termNode t
,
3938 /*@only@*/ termNode right
)
3942 if ((t
== (termNode
) 0) || (t
->name
== NULL
) || (t
->name
->isOpId
))
3944 llbugexitlit ("updateSqBracketededNode: expect opForm in nameNode");
3947 op
= t
->name
->content
.opform
;
3948 llassert (op
!= NULL
);
3950 if (left
== (termNode
) 0)
3952 if (right
== (termNode
) 0)
3954 /* op->kind is not changed */
3958 op
->kind
= OPF_BMIDDLEM
;
3959 op
->key
= opFormNode2key (op
, OPF_BMIDDLEM
);
3960 termNodeList_addh (t
->args
, right
);
3965 termNodeList_addl (t
->args
, left
);
3967 if (right
== (termNode
) 0)
3969 op
->kind
= OPF_BMMIDDLE
;
3970 op
->key
= opFormNode2key (op
, OPF_BMMIDDLE
);
3974 op
->kind
= OPF_BMMIDDLEM
;
3975 op
->key
= opFormNode2key (op
, OPF_BMMIDDLEM
);
3976 termNodeList_addh (t
->args
, right
);
3983 makeSqBracketedNode (ltoken lbracket
,
3984 termNodeList args
, ltoken rbracket
)
3986 termNode t
= (termNode
) dmalloc (sizeof (*t
));
3991 t
->error_reported
= FALSE
;
3994 size
= termNodeList_size (args
);
3995 opform
= makeOpFormNode (lbracket
, OPF_BMIDDLE
, opFormUnion_createMiddle (size
),
3997 nn
= makeNameNodeForm (opform
);
3999 t
->kind
= TRM_APPLICATION
;
4001 t
->sort
= sort_makeNoSort ();
4003 t
->possibleSorts
= sortSet_new ();
4004 t
->possibleOps
= lslOpSet_new ();
4005 /* do sort checking later, not here, incomplete parse */
4010 makeMatchedNode (ltoken open
, termNodeList args
, ltoken close
)
4012 /* matched : open args close */
4013 termNode t
= (termNode
) dmalloc (sizeof (*t
));
4018 t
->error_reported
= FALSE
;
4021 size
= termNodeList_size (args
);
4022 opform
= makeOpFormNode (open
, OPF_MIDDLE
, opFormUnion_createMiddle (size
), close
);
4023 nn
= makeNameNodeForm (opform
);
4025 t
->kind
= TRM_APPLICATION
;
4027 t
->sort
= sort_makeNoSort ();
4029 t
->possibleSorts
= sortSet_new ();
4030 t
->possibleOps
= lslOpSet_new ();
4031 /* do sort checking later, not here, incomplete parse */
4036 makeSimpleTermNode (ltoken varid
)
4038 sort theSort
= sort_makeNoSort ();
4042 termNode n
= (termNode
) dmalloc (sizeof (*n
));
4044 n
->error_reported
= FALSE
;
4046 n
->name
= (nameNode
) 0;
4048 n
->args
= termNodeList_new ();
4049 n
->possibleSorts
= sortSet_new ();
4050 n
->possibleOps
= lslOpSet_new ();
4052 sym
= ltoken_getText (varid
);
4054 /* lookup current scope */
4055 vi
= symtable_varInfoInScope (g_symtab
, sym
);
4057 if (varInfo_exists (vi
))
4063 (void) sortSet_insert (n
->possibleSorts
, theSort
);
4066 { /* need to handle LCL constants */
4067 vi
= symtable_varInfo (g_symtab
, sym
);
4069 if (varInfo_exists (vi
) && vi
->kind
== VRK_CONST
)
4072 n
->kind
= TRM_CONST
;
4075 (void) sortSet_insert (n
->possibleSorts
, theSort
);
4078 { /* and LSL operators (true, false, new, nil, etc) */
4079 nameNode nn
= makeNameNodeId (ltoken_copy (varid
));
4080 oi
= symtable_opInfo (g_symtab
, nn
);
4082 if (opInfo_exists (oi
) && (oi
->name
->isOpId
) &&
4083 !sigNodeSet_isEmpty (oi
->signatures
))
4085 sigNodeSet_elements (oi
->signatures
, x
)
4087 if (ltokenList_empty (x
->domain
))
4088 /* yes, it really is empty, not not empty */
4090 lslOp op
= (lslOp
) dmalloc (sizeof (*op
));
4092 op
->name
= nameNode_copy (nn
);
4094 (void) sortSet_insert (n
->possibleSorts
, sigNode_rangeSort (x
));
4095 (void) lslOpSet_insert (n
->possibleOps
, op
);
4097 } end_sigNodeSet_elements
;
4102 if (sortSet_size (n
->possibleSorts
) == 0)
4106 message ("Unrecognized identifier (constant, variable or operator): %s",
4107 ltoken_getRawString (varid
)));
4111 n
->sort
= sort_makeNoSort ();
4113 n
->kind
= TRM_ZEROARY
;
4121 makeSelectTermNode (termNode pri
, ltoken select
, /*@dependent@*/ ltoken id
)
4123 termNode t
= (termNode
) dmalloc (sizeof (*t
));
4124 opFormNode opform
= makeOpFormNode (select
,
4125 OPF_MSELECT
, opFormUnion_createAnyOp (id
),
4127 nameNode nn
= makeNameNodeForm (opform
);
4128 termNodeList args
= termNodeList_new ();
4130 t
->error_reported
= FALSE
;
4133 t
->kind
= TRM_APPLICATION
;
4134 termNodeList_addh (args
, pri
);
4136 t
->kind
= TRM_APPLICATION
;
4137 t
->sort
= sort_makeNoSort ();
4139 t
->possibleSorts
= sortSet_new ();
4140 t
->possibleOps
= lslOpSet_new ();
4146 makeMapTermNode (termNode pri
, ltoken map
, /*@dependent@*/ ltoken id
)
4148 termNode t
= (termNode
) dmalloc (sizeof (*t
));
4149 opFormNode opform
= makeOpFormNode (map
, OPF_MMAP
, opFormUnion_createAnyOp (id
),
4151 nameNode nn
= makeNameNodeForm (opform
);
4152 termNodeList args
= termNodeList_new ();
4154 t
->error_reported
= FALSE
;
4156 t
->kind
= TRM_APPLICATION
;
4158 termNodeList_addh (args
, pri
);
4160 t
->kind
= TRM_APPLICATION
;
4161 t
->sort
= sort_makeNoSort ();
4163 t
->possibleSorts
= sortSet_new ();
4164 t
->possibleOps
= lslOpSet_new ();
4169 makeLiteralTermNode (ltoken tok
, sort s
)
4171 nameNode nn
= makeNameNodeId (ltoken_copy (tok
));
4172 opInfo oi
= symtable_opInfo (g_symtab
, nn
);
4173 lslOp op
= (lslOp
) dmalloc (sizeof (*op
));
4174 termNode n
= (termNode
) dmalloc (sizeof (*n
));
4179 n
->error_reported
= FALSE
;
4181 n
->kind
= TRM_LITERAL
;
4183 n
->given
= sort_makeNoSort ();
4185 n
->args
= termNodeList_new ();
4186 n
->possibleSorts
= sortSet_new ();
4187 n
->possibleOps
= lslOpSet_new ();
4189 /* look up signatures for this operator too */
4191 range
= ltoken_create (simpleId
, sort_getLsymbol (s
));
4192 sign
= makesigNode (ltoken_undefined
, ltokenList_new (),
4193 ltoken_copy (range
));
4195 if (opInfo_exists (oi
) && (oi
->name
->isOpId
)
4196 && (sigNodeSet_size (oi
->signatures
) > 0))
4198 sigNodeSet_elements (oi
->signatures
, x
)
4200 if (ltokenList_empty (x
->domain
))
4202 lslOp opn
= (lslOp
) dmalloc (sizeof (*opn
));
4205 opn
->name
= nameNode_copy (nn
);
4207 sort
= sigNode_rangeSort (x
);
4208 (void) sortSet_insert (n
->possibleSorts
, sort
);
4209 (void) lslOpSet_insert (n
->possibleOps
, opn
);
4211 } end_sigNodeSet_elements
;
4214 /* insert into literal term */
4215 (void) sortSet_insert (n
->possibleSorts
, s
);
4217 op
->name
= nameNode_copy (nn
);
4218 op
->signature
= sign
;
4219 (void) lslOpSet_insert (n
->possibleOps
, op
);
4221 /* enter the literal as an operator into the operator table */
4222 /* 8/9/93. C's char constant 'c' syntax conflicts
4223 with LSL's lslinit.lsi table. Throw out, because it's not
4225 /* symtable_enterOp (g_symtab, nn, sign); */
4230 lslOp opn
= (lslOp
) dmalloc (sizeof (*opn
));
4232 /* if it is a C int, we should overload it as double too because
4233 C allows you to say "x > 2". */
4235 (void) sortSet_insert (n
->possibleSorts
, g_sortDouble
);
4237 ltoken_setText (range
, lsymbol_fromChars ("double"));
4238 osign
= makesigNode (ltoken_undefined
, ltokenList_new (), range
);
4239 opn
->name
= nameNode_copy (nn
);
4240 opn
->signature
= osign
;
4241 (void) lslOpSet_insert (n
->possibleOps
, opn
);
4243 symtable_enterOp (g_symtab
, nameNode_copySafe (nn
), sigNode_copy (osign
));
4247 ltoken_free (range
);
4250 /* future: could overload cstrings to be both char_Vec as well as
4258 makeUnchangedTermNode1 (ltoken op
, /*@unused@*/ ltoken all
)
4260 termNode t
= (termNode
) dmalloc (sizeof (*t
));
4262 t
->error_reported
= FALSE
;
4264 t
->kind
= TRM_UNCHANGEDALL
;
4265 t
->sort
= g_sortBool
;
4267 t
->given
= sort_makeNoSort ();
4268 t
->name
= NULL
; /*< missing this >*/
4269 t
->args
= termNodeList_new ();
4270 t
->possibleSorts
= sortSet_new ();
4271 t
->possibleOps
= lslOpSet_new ();
4272 (void) sortSet_insert (t
->possibleSorts
, t
->sort
);
4280 makeUnchangedTermNode2 (ltoken op
, storeRefNodeList x
)
4282 termNode t
= (termNode
) dmalloc (sizeof (*t
));
4286 t
->name
= NULL
; /*< missing this >*/
4287 t
->error_reported
= FALSE
;
4289 t
->kind
= TRM_UNCHANGEDOTHERS
;
4290 t
->sort
= g_sortBool
;
4293 t
->given
= sort_makeNoSort ();
4294 t
->possibleSorts
= sortSet_new ();
4295 t
->possibleOps
= lslOpSet_new ();
4296 t
->args
= termNodeList_new ();
4298 (void) sortSet_insert (t
->possibleSorts
, t
->sort
);
4299 /* check storeRefNode's are mutable, uses sort of term */
4301 storeRefNodeList_elements (x
, sto
)
4303 if (storeRefNode_isTerm (sto
))
4305 sort
= sto
->content
.term
->sort
;
4306 if (!sort_mutable (sort
))
4308 errtok
= termNode_errorToken (sto
->content
.term
);
4310 message ("Term denoting immutable object used in unchanged list: %q",
4311 termNode_unparse (sto
->content
.term
)));
4316 if (storeRefNode_isType (sto
))
4318 lclTypeSpecNode type
= sto
->content
.type
;
4319 sort
= lclTypeSpecNode2sort (type
);
4320 if (!sort_mutable (sort
))
4322 errtok
= lclTypeSpecNode_errorToken (type
);
4323 lclerror (errtok
, message ("Immutable type used in unchanged list: %q",
4324 sort_unparse (sort
)));
4328 } end_storeRefNodeList_elements
;
4334 makeSizeofTermNode (ltoken op
, lclTypeSpecNode type
)
4336 termNode t
= (termNode
) dmalloc (sizeof (*t
));
4338 t
->name
= NULL
; /*< missing this >*/
4339 t
->error_reported
= FALSE
;
4341 t
->kind
= TRM_SIZEOF
;
4342 t
->sort
= g_sortInt
;
4344 t
->sizeofField
= type
;
4345 t
->given
= sort_makeNoSort ();
4346 t
->possibleSorts
= sortSet_new ();
4347 t
->possibleOps
= lslOpSet_new ();
4348 t
->args
= termNodeList_new ();
4350 (void) sortSet_insert (t
->possibleSorts
, t
->sort
);
4351 /* nothing to check */
4357 claimNode_unparse (claimNode c
)
4359 if (c
!= (claimNode
) 0)
4361 cstring s
= message ("claims (%q)%q{\n%q",
4362 paramNodeList_unparse (c
->params
),
4363 varDeclarationNodeList_unparse (c
->globals
),
4364 lclPredicateNode_unparse (c
->require
));
4366 if (c
->body
!= NULL
)
4368 s
= message ("%qbody {%q}\n", s
, programNode_unparse (c
->body
));
4370 s
= message ("%q%q}\n", s
, lclPredicateNode_unparse (c
->ensures
));
4373 return cstring_undefined
;
4375 # endif /* DEADCODE */
4378 WrongArity (ltoken tok
, int expect
, int size
)
4380 lclerror (tok
, message ("Expecting %d arguments but given %d", expect
, size
));
4384 printTermNode2 (/*@null@*/ opFormNode op
, termNodeList args
, sort sort
)
4386 if (op
!= (opFormNode
) 0)
4388 cstring s
= cstring_undefined
;
4392 if (sort_isNoSort (sort
))
4394 sortText
= message (": %s", cstring_fromChars (lsymbol_toChars (sort_getLsymbol (sort
))));
4395 sortSpace
= cstring_makeLiteral (" ");
4399 sortText
= cstring_undefined
;
4400 sortSpace
= cstring_undefined
;
4407 int size
= termNodeList_size (args
);
4411 s
= message ("if %q then %q else %q\n",
4412 termNode_unparse (termNodeList_getN (args
, 0)),
4413 termNode_unparse (termNodeList_getN (args
, 1)),
4414 termNode_unparse (termNodeList_getN (args
, 2)));
4418 WrongArity (op
->tok
, 3, size
);
4419 s
= cstring_makeLiteral ("if __ then __ else __");
4421 s
= message ("%q%s", s
, sortText
);
4426 s
= message ("%s %s",
4427 ltoken_getRawString (op
->content
.anyop
),
4433 int size
= termNodeList_size (args
);
4437 s
= message ("%q ", termNode_unparse (termNodeList_head (args
)));
4441 WrongArity (op
->content
.anyop
, 1, size
);
4442 s
= cstring_makeLiteral ("__ ");
4444 s
= message ("%q%s%s", s
, ltoken_getRawString (op
->content
.anyop
),
4450 int size
= termNodeList_size (args
);
4452 s
= message ("%s ", ltoken_getRawString (op
->content
.anyop
));
4456 s
= message ("%q%q", s
, termNode_unparse (termNodeList_head (args
)));
4460 WrongArity (op
->content
.anyop
, 1, size
);
4461 s
= message ("%q__", s
);
4463 s
= message ("%q%s", s
, sortText
);
4468 int size
= termNodeList_size (args
);
4472 s
= message ("%q %s %q",
4473 termNode_unparse (termNodeList_getN (args
, 0)),
4474 ltoken_getRawString (op
->content
.anyop
),
4475 termNode_unparse (termNodeList_getN (args
, 1)));
4479 WrongArity (op
->content
.anyop
, 2, size
);
4480 s
= message ("__ %s __", ltoken_getRawString (op
->content
.anyop
));
4482 s
= message ("%q%s", s
, sortText
);
4487 int size
= termNodeList_size (args
);
4488 int expect
= op
->content
.middle
;
4490 /* ymtan ? use { or openSym token ? */
4494 s
= message ("{%q}", termNodeList_unparse (args
));
4498 WrongArity (op
->tok
, expect
, size
);
4499 s
= cstring_makeLiteral ("{ * }");
4502 s
= message ("%q%s", s
, sortText
);
4507 int size
= termNodeList_size (args
);
4508 int expect
= op
->content
.middle
+ 1;
4512 s
= message ("%q{%q}",
4513 termNode_unparse (termNodeList_head (args
)),
4514 termNodeList_unparseTail (args
));
4518 WrongArity (op
->tok
, expect
, size
);
4519 s
= cstring_makeLiteral ("__ { * }");
4522 s
= message ("%q%s", s
, sortText
);
4527 int size
= termNodeList_size (args
);
4528 int expect
= op
->content
.middle
+ 1;
4532 termNodeList_finish (args
);
4534 s
= message ("{%q}%s%s%q",
4535 termNodeList_unparseToCurrent (args
),
4536 sortText
, sortSpace
,
4537 termNode_unparse (termNodeList_current (args
)));
4541 WrongArity (op
->tok
, expect
, size
);
4543 s
= message ("{ * }%s __", sortText
);
4545 /* used to put in extra space! evs 94-01-05 */
4551 int size
= termNodeList_size (args
);
4552 int expect
= op
->content
.middle
+ 2;
4556 termNodeList_finish (args
);
4558 s
= message ("%q {%q} %s%s%q",
4559 termNode_unparse (termNodeList_head (args
)),
4560 termNodeList_unparseSecondToCurrent (args
),
4561 sortText
, sortSpace
,
4562 termNode_unparse (termNodeList_current (args
)));
4566 WrongArity (op
->tok
, expect
, size
);
4567 s
= message ("__ { * } %s __", sortText
);
4569 /* also had extra space? */
4575 int size
= termNodeList_size (args
);
4576 int expect
= op
->content
.middle
;
4580 s
= message ("[%q]", termNodeList_unparse (args
));
4584 WrongArity (op
->tok
, expect
, size
);
4585 s
= cstring_makeLiteral ("[ * ]");
4587 s
= message ("%q%s", s
, sortText
);
4592 int size
= termNodeList_size (args
);
4593 int expect
= op
->content
.middle
+ 1;
4597 s
= message ("%q[%q]",
4598 termNode_unparse (termNodeList_head (args
)),
4599 termNodeList_unparseTail (args
));
4603 WrongArity (op
->tok
, expect
, size
);
4604 s
= cstring_makeLiteral ("__ [ * ]");
4607 s
= message ("%q%s", s
, sortText
);
4612 int size
= termNodeList_size (args
);
4613 int expect
= op
->content
.middle
+ 1;
4617 s
= message ("%q[%q] __",
4618 termNode_unparse (termNodeList_head (args
)),
4619 termNodeList_unparseTail (args
));
4623 WrongArity (op
->tok
, expect
, size
);
4624 s
= cstring_makeLiteral ("__ [ * ] __");
4626 s
= message ("%q%s", s
, sortText
);
4631 int size
= termNodeList_size (args
);
4632 int expect
= op
->content
.middle
+ 1;
4636 termNodeList_finish (args
);
4638 s
= message ("[%q]%s%s%q",
4639 termNodeList_unparseToCurrent (args
),
4640 sortText
, sortSpace
,
4641 termNode_unparse (termNodeList_current (args
)));
4645 WrongArity (op
->tok
, expect
, size
);
4646 s
= cstring_makeLiteral ("[ * ] __");
4652 { /* ymtan constant, check args ? */
4653 s
= cstring_prependChar ('.', ltoken_getRawString (op
->content
.id
));
4657 s
= cstring_concat (cstring_makeLiteralTemp ("->"),
4658 ltoken_getRawString (op
->content
.id
));
4662 int size
= termNodeList_size (args
);
4666 s
= message ("%q.%s", termNode_unparse (termNodeList_head (args
)),
4667 ltoken_getRawString (op
->content
.id
));
4671 WrongArity (op
->content
.id
, 1, size
);
4672 s
= cstring_concat (cstring_makeLiteralTemp ("__."),
4673 ltoken_getRawString (op
->content
.id
));
4679 int size
= termNodeList_size (args
);
4683 s
= message ("%q->%s", termNode_unparse (termNodeList_head (args
)),
4684 ltoken_getRawString (op
->content
.id
));
4688 WrongArity (op
->content
.id
, 1, size
);
4689 s
= cstring_concat (cstring_makeLiteralTemp ("__->"),
4690 ltoken_getRawString (op
->content
.id
));
4696 cstring_free (sortSpace
);
4697 cstring_free (sortText
);
4700 return cstring_undefined
;
4704 termNode_unparse (/*@null@*/ termNode n
)
4706 cstring s
= cstring_undefined
;
4707 cstring back
= cstring_undefined
;
4708 cstring front
= cstring_undefined
;
4711 if (n
!= (termNode
) 0)
4713 for (count
= n
->wrapped
; count
> 0; count
--)
4715 front
= cstring_appendChar (front
, '(');
4716 back
= cstring_appendChar (back
, ')');
4725 s
= cstring_copy (ltoken_getRawString (n
->literal
));
4727 case TRM_APPLICATION
:
4729 nameNode nn
= n
->name
;
4730 if (nn
!= (nameNode
) 0)
4734 s
= message ("%s (%q) ",
4735 ltoken_getRawString (nn
->content
.opid
),
4736 termNodeList_unparse (n
->args
));
4737 /* must we handle n->given ? skip for now */
4741 s
= message ("%q ", printTermNode2 (nn
->content
.opform
, n
->args
, n
->given
));
4747 (message ("termNode_unparse: expect non-empty nameNode: TRM_APPLICATION: %q",
4748 nameNode_unparse (nn
)));
4752 case TRM_UNCHANGEDALL
:
4753 s
= cstring_makeLiteral ("unchanged (all)");
4755 case TRM_UNCHANGEDOTHERS
:
4756 s
= message ("unchanged (%q)", storeRefNodeList_unparse (n
->unchanged
));
4759 s
= message ("sizeof (%q)", lclTypeSpecNode_unparse (n
->sizeofField
));
4761 case TRM_QUANTIFIER
:
4763 quantifiedTermNode x
= n
->quantified
;
4764 s
= message ("%q%s%q%s",
4765 quantifierNodeList_unparse (x
->quantifiers
),
4766 ltoken_getRawString (x
->open
),
4767 termNode_unparse (x
->body
),
4768 ltoken_getRawString (x
->close
));
4773 return (message ("%q%q%q", front
, s
, back
));
4776 static void modifyNode_free (/*@null@*/ /*@only@*/ modifyNode m
)
4778 if (m
!= (modifyNode
) 0)
4781 if (m
->hasStoreRefList
)
4783 storeRefNodeList_free (m
->list
);
4788 ltoken_free (m
->tok
);
4795 modifyNode_unparse (/*@null@*/ modifyNode m
)
4797 if (m
!= (modifyNode
) 0)
4799 if (m
->hasStoreRefList
)
4801 return (message (" modifies %q; \n", storeRefNodeList_unparse (m
->list
)));
4805 if (m
->modifiesNothing
)
4807 return (cstring_makeLiteral ("modifies nothing; \n"));
4811 return (cstring_makeLiteral ("modifies anything; \n"));
4815 return cstring_undefined
;
4819 programNode_unparse (programNode p
)
4821 if (p
!= (programNode
) 0)
4823 cstring s
= cstring_undefined
;
4830 cstring back
= cstring_undefined
;
4832 for (count
= p
->wrapped
; count
> 0; count
--)
4834 s
= cstring_appendChar (s
, '(');
4835 back
= cstring_appendChar (back
, ')');
4837 s
= message ("%q%q%q", s
, stmtNode_unparse (p
->content
.self
), back
);
4841 s
= message ("*(%q)", programNodeList_unparse (p
->content
.args
));
4844 s
= message ("|(%q)", programNodeList_unparse (p
->content
.args
));
4847 s
= programNodeList_unparse (p
->content
.args
);
4853 return cstring_undefined
;
4857 stmtNode_unparse (stmtNode x
)
4859 cstring s
= cstring_undefined
;
4861 if (x
!= (stmtNode
) 0)
4863 if (ltoken_isValid (x
->lhs
))
4865 s
= cstring_concat (ltoken_getRawString (x
->lhs
),
4866 cstring_makeLiteralTemp (" = "));
4869 s
= message ("%q%s (%q)", s
,
4870 ltoken_getRawString (x
->operator),
4871 termNodeList_unparse (x
->args
));
4876 # endif /* DEADCODE */
4879 makelslOpNode (/*@only@*/ /*@null@*/ nameNode name
,
4880 /*@dependent@*/ sigNode s
)
4882 lslOp x
= (lslOp
) dmalloc (sizeof (*x
));
4887 /* enter operator info into symtab */
4888 /* if not, they may need to be renamed in LCL imports */
4890 if (g_lslParsingTraits
)
4894 symtable_enterOp (g_symtab
, nameNode_copySafe (name
), sigNode_copy (s
));
4899 /* nameNode_free (name); */ /* YIKES! */
4907 lslOp_unparse (lslOp x
)
4909 char *s
= mstring_createEmpty ();
4913 s
= mstring_concatFree (s
, cstring_toCharsSafe (nameNode_unparse (x
->name
)));
4915 if (x
->signature
!= (sigNode
) 0)
4917 s
= mstring_concatFree (s
, cstring_toCharsSafe (sigNode_unparse (x
->signature
)));
4921 return cstring_fromCharsO (s
);
4923 # endif /* DEADCODE */
4926 sameOpFormNode (/*@null@*/ opFormNode n1
, /*@null@*/ opFormNode n2
)
4937 if (n1
->kind
== n2
->kind
)
4946 return (ltoken_similar (n1
->content
.anyop
, n2
->content
.anyop
));
4949 /* want to treat eq and = the same */
4950 return ltoken_similar (n1
->content
.anyop
, n2
->content
.anyop
);
4956 /* need to check the rawText of openSym and closeSym */
4957 if ((int) n1
->content
.middle
== (int) n2
->content
.middle
)
4959 if (lsymbol_equal (ltoken_getRawText (n1
->tok
),
4960 ltoken_getRawText (n2
->tok
)) &&
4961 lsymbol_equal (ltoken_getRawText (n1
->close
),
4962 ltoken_getRawText (n2
->close
)))
4970 return ((int) n1
->content
.middle
== (int) n2
->content
.middle
);
4975 return (ltoken_similar (n1
->content
.id
, n2
->content
.id
));
4982 sameNameNode (/*@null@*/ nameNode n1
, /*@null@*/ nameNode n2
)
4986 if (n1
!= (nameNode
) 0 && n2
!= (nameNode
) 0)
4988 if (bool_equal (n1
->isOpId
, n2
->isOpId
))
4991 return (ltoken_similar (n1
->content
.opid
, n2
->content
.opid
));
4993 return sameOpFormNode (n1
->content
.opform
,
4994 n2
->content
.opform
);
5000 void CTypesNode_free (/*@only@*/ /*@null@*/ CTypesNode x
)
5004 ltokenList_free (x
->ctypes
);
5009 /*@null@*/ CTypesNode
CTypesNode_copy (/*@null@*/ CTypesNode x
)
5013 CTypesNode newnode
= (CTypesNode
) dmalloc (sizeof (*newnode
));
5014 newnode
->intfield
= x
->intfield
;
5015 newnode
->ctypes
= ltokenList_copy (x
->ctypes
);
5016 newnode
->sort
= x
->sort
;
5026 /*@only@*/ CTypesNode
5027 makeCTypesNode (/*@only@*/ CTypesNode ctypes
, ltoken ct
)
5029 /*@only@*/ CTypesNode newnode
;
5033 if (ctypes
== (CTypesNode
) NULL
)
5035 newnode
= (CTypesNode
) dmalloc (sizeof (*newnode
));
5036 newnode
->intfield
= 0;
5037 newnode
->ctypes
= ltokenList_new ();
5038 newnode
->sort
= sort_makeNoSort ();
5045 if ((ltoken_getIntField (ct
) & newnode
->intfield
) != 0)
5049 ("Duplicate type specifier ignored: %s",
5052 (lclctype_toSortDebug (ltoken_getIntField (ct
))))));
5054 /* evs --- don't know how to generator this error */
5056 /* Use previous value, to keep things consistent */
5061 sortbits
= newnode
->intfield
| ltoken_getIntField (ct
);
5062 sortname
= lclctype_toSort (sortbits
);
5064 if (sortname
== lsymbol_fromChars ("error"))
5066 lclerror (ct
, cstring_makeLiteral ("Invalid combination of type specifiers"));
5070 newnode
->intfield
= sortbits
;
5073 ltokenList_addh (newnode
->ctypes
, ct
);
5076 ** Sorts are assigned after CTypesNode is created during parsing,
5077 ** see bison grammar.
5083 /*@only@*/ CTypesNode
5084 makeTypeSpecifier (ltoken typedefname
)
5086 CTypesNode newnode
= (CTypesNode
) dmalloc (sizeof (*newnode
));
5087 typeInfo ti
= symtable_typeInfo (g_symtab
, ltoken_getText (typedefname
));
5089 newnode
->intfield
= 0;
5090 newnode
->ctypes
= ltokenList_singleton (ltoken_copy (typedefname
));
5092 /* if we see "bool" include bool.h header file */
5094 if (ltoken_getText (typedefname
) == lsymbol_bool
)
5099 if (typeInfo_exists (ti
))
5101 /* must we be concern about whether this type is exported by module?
5102 No. Because all typedef's are exported. No hiding supported. */
5103 /* Later, may want to keep types around too */
5104 /* 3/2/93, use underlying sort */
5105 newnode
->sort
= sort_getUnderlying (ti
->basedOn
);
5109 lclerror (typedefname
, message ("Unrecognized type: %s",
5110 ltoken_getRawString (typedefname
)));
5111 /* evs --- Don't know how to get this message */
5113 newnode
->sort
= sort_makeNoSort ();
5116 ltoken_free (typedefname
);
5120 bool sigNode_equal (sigNode n1
, sigNode n2
)
5122 /* n1 and n2 are never 0 */
5124 return ((n1
== n2
) ||
5125 (n1
->key
== n2
->key
&&
5126 ltoken_similar (n1
->range
, n2
->range
) &&
5127 ltokenList_equal (n1
->domain
, n2
->domain
)));
5131 typeExpr2ptrSort (sort base
, /*@null@*/ typeExpr t
)
5133 if (t
!= (typeExpr
) 0)
5140 return typeExpr2ptrSort (sort_makePtr (ltoken_undefined
, base
),
5141 t
->content
.pointer
);
5143 return typeExpr2ptrSort (sort_makeArr (ltoken_undefined
, base
),
5144 t
->content
.array
.elementtype
);
5146 /* map all hof types to some sort of SRT_HOF */
5147 return sort_makeHOFSort (base
);
5154 typeExpr2returnSort (sort base
, /*@null@*/ typeExpr t
)
5156 if (t
!= (typeExpr
) 0)
5163 return typeExpr2returnSort (sort_makePtr (ltoken_undefined
, base
),
5164 t
->content
.pointer
);
5166 return typeExpr2returnSort (sort_makeArr (ltoken_undefined
, base
),
5167 t
->content
.array
.elementtype
);
5169 return typeExpr2returnSort (base
, t
->content
.function
.returntype
);
5176 lclTypeSpecNode2sort (lclTypeSpecNode type
)
5178 if (type
!= (lclTypeSpecNode
) 0)
5183 llassert (type
->content
.type
!= NULL
);
5184 return sort_makePtrN (type
->content
.type
->sort
, type
->pointers
);
5185 case LTS_STRUCTUNION
:
5186 llassert (type
->content
.structorunion
!= NULL
);
5187 return sort_makePtrN (type
->content
.structorunion
->sort
, type
->pointers
);
5189 llassert (type
->content
.enumspec
!= NULL
);
5190 return sort_makePtrN (type
->content
.enumspec
->sort
, type
->pointers
);
5192 return (lclTypeSpecNode2sort (type
->content
.conj
->a
));
5195 return (sort_makeNoSort ());
5199 checkAndEnterTag (tagKind k
, ltoken opttagid
)
5201 /* should be tagKind, instead of int */
5203 sort sort
= sort_makeNoSort ();
5205 if (!ltoken_isUndefined (opttagid
))
5211 sort
= sort_makeStr (opttagid
);
5215 sort
= sort_makeUnion (opttagid
);
5218 sort
= sort_makeEnum (opttagid
);
5222 /* see if it is already in symbol table */
5223 t
= symtable_tagInfo (g_symtab
, ltoken_getText (opttagid
));
5225 if (tagInfo_exists (t
))
5227 if (t
->kind
== TAG_FWDUNION
|| t
->kind
== TAG_FWDSTRUCT
)
5229 /* this is fine, for mutually recursive types */
5232 { /* this is not good, complain later */
5254 message ("Tag redefined: %s %s", cstring_makeLiteralTemp (s
),
5255 ltoken_getRawString (opttagid
)));
5259 ltoken_free (opttagid
);
5263 tagInfo newnode
= (tagInfo
) dmalloc (sizeof (*newnode
));
5265 newnode
->sort
= sort
;
5267 newnode
->id
= opttagid
;
5268 newnode
->imported
= FALSE
;
5269 newnode
->content
.decls
= stDeclNodeList_new ();
5271 (void) symtable_enterTag (g_symtab
, newnode
);
5275 return sort_getLsymbol (sort
);
5279 extractReturnSort (lclTypeSpecNode t
, declaratorNode d
)
5282 sort
= lclTypeSpecNode2sort (t
);
5283 sort
= typeExpr2returnSort (sort
, d
->type
);
5288 signNode_free (/*@only@*/ signNode sn
)
5290 sortList_free (sn
->domain
);
5291 ltoken_free (sn
->tok
);
5296 signNode_unparse (signNode sn
)
5298 cstring s
= cstring_undefined
;
5300 if (sn
!= (signNode
) 0)
5302 s
= message (": %q -> %s", sortList_unparse (sn
->domain
),
5303 sort_unparseName (sn
->range
));
5308 static /*@only@*/ pairNodeList
5309 globalList_toPairNodeList (globalList g
)
5311 /* expect list to be globals, drop private ones */
5312 pairNodeList result
= pairNodeList_new ();
5314 declaratorNode vdnode
;
5315 lclTypeSpecNode type
;
5317 initDeclNodeList decls
;
5319 varDeclarationNodeList_elements (g
, x
)
5327 if (x
->isGlobal
&& !x
->isPrivate
)
5332 initDeclNodeList_elements (decls
, init
)
5335 p
= (pairNode
) dmalloc (sizeof (*p
));
5337 vdnode
= init
->declarator
;
5338 /* sym = ltoken_getText (vdnode->id); */
5339 /* 2/21/93, not sure if it should be extractReturnSort,
5340 or some call to typeExpr2ptrSort */
5341 sort
= extractReturnSort (type
, vdnode
);
5342 p
->sort
= sort_makeGlobal (sort
);
5343 /* if (!sort_isArrayKind (sort)) p->sort = sort_makeObj (sort);
5344 else p->sort = sort; */
5345 /* p->name = sym; */
5346 p
->tok
= ltoken_copy (vdnode
->id
);
5347 pairNodeList_addh (result
, p
);
5348 } end_initDeclNodeList_elements
;
5351 } end_varDeclarationNodeList_elements
;
5356 enteringFcnScope (lclTypeSpecNode t
, declaratorNode d
, globalList g
)
5358 scopeInfo si
= (scopeInfo
) dmalloc (sizeof (*si
));
5359 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
5361 ltoken result
= ltoken_copy (ltoken_id
);
5362 pairNodeList paramPairs
, globals
;
5363 fctInfo fi
= (fctInfo
) dmalloc (sizeof (*fi
));
5364 signNode sign
= (signNode
) dmalloc (sizeof (*sign
));
5365 sortList domain
= sortList_new ();
5366 unsigned long int key
;
5368 paramPairs
= extractParams (d
->type
);
5369 returnSort
= extractReturnSort (t
, d
);
5370 globals
= globalList_toPairNodeList (g
);
5372 sign
->tok
= ltoken_undefined
;
5373 sign
->range
= returnSort
;
5375 key
= MASH (0, sort_getLsymbol (returnSort
));
5377 pairNodeList_elements (paramPairs
, p
)
5379 sortList_addh (domain
, p
->sort
);
5380 key
= MASH (key
, sort_getLsymbol (p
->sort
));
5381 } end_pairNodeList_elements
;
5383 sign
->domain
= domain
;
5386 /* push fcn onto symbol table stack first */
5387 fi
->id
= ltoken_copy (d
->id
);
5389 fi
->signature
= sign
;
5390 fi
->globals
= globals
;
5392 (void) symtable_enterFct (g_symtab
, fi
);
5394 /* push new fcn scope */
5396 symtable_enterScope (g_symtab
, si
);
5398 /* add "result" with return type to current scope */
5399 ltoken_setText (result
, lsymbol_fromChars ("result"));
5402 vi
->sort
= sort_makeFormal (returnSort
); /* make appropriate values */
5403 vi
->kind
= VRK_PARAM
;
5406 (void) symtable_enterVar (g_symtab
, vi
);
5410 ** pust globals first (they are in outer scope)
5413 /* push onto symbol table the global variables declared in this function,
5414 together with their respective sorts */
5416 pairNodeList_elements (globals
, gl
)
5418 ltoken_free (vi
->id
);
5419 vi
->id
= ltoken_copy (gl
->tok
);
5420 vi
->kind
= VRK_GLOBAL
;
5421 vi
->sort
= gl
->sort
;
5422 (void) symtable_enterVar (g_symtab
, vi
);
5423 } end_pairNodeList_elements
;
5426 ** could enter a new scope; instead, warn when variable shadows global
5431 ** push onto symbol table the formal parameters of this function,
5432 ** together with their respective sorts
5435 pairNodeList_elements (paramPairs
, pair
)
5437 ltoken_free (vi
->id
);
5438 vi
->id
= ltoken_copy (pair
->tok
);
5439 vi
->sort
= pair
->sort
;
5440 vi
->kind
= VRK_PARAM
;
5441 (void) symtable_enterVar (g_symtab
, vi
);
5442 } end_pairNodeList_elements
;
5444 pairNodeList_free (paramPairs
);
5449 enteringClaimScope (paramNodeList params
, globalList g
)
5451 scopeInfo si
= (scopeInfo
) dmalloc (sizeof (*si
));
5452 pairNodeList globals
;
5453 lclTypeSpecNode paramtype
;
5457 globals
= globalList_toPairNodeList (g
);
5458 /* push new claim scope */
5459 si
->kind
= SPE_CLAIM
;
5461 symtable_enterScope (g_symtab
, si
);
5463 /* push onto symbol table the formal parameters of this function,
5464 together with their respective sorts */
5466 paramNodeList_elements (params
, param
)
5468 paramdecl
= param
->paramdecl
;
5469 paramtype
= param
->type
;
5470 if (paramdecl
!= (typeExpr
) 0 && paramtype
!= (lclTypeSpecNode
) 0)
5472 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
5474 sort
= lclTypeSpecNode2sort (paramtype
);
5475 sort
= sort_makeFormal (sort
);
5476 vi
->sort
= typeExpr2ptrSort (sort
, paramdecl
);
5477 vi
->id
= ltoken_copy (extractDeclarator (paramdecl
));
5478 vi
->kind
= VRK_PARAM
;
5481 (void) symtable_enterVar (g_symtab
, vi
);
5484 } end_paramNodeList_elements
;
5486 /* push onto symbol table the global variables declared in this function,
5487 together with their respective sorts */
5489 pairNodeList_elements (globals
, g2
)
5491 varInfo vi
= (varInfo
) dmalloc (sizeof (*vi
));
5493 vi
->id
= ltoken_copy (g2
->tok
);
5494 vi
->kind
= VRK_GLOBAL
;
5495 vi
->sort
= g2
->sort
;
5498 /* should catch duplicates in formals */
5499 (void) symtable_enterVar (g_symtab
, vi
);
5501 } end_pairNodeList_elements
;
5503 pairNodeList_free (globals
);
5504 /* should not free it here! ltoken_free (claimId); @*/
5507 static /*@only@*/ pairNodeList
5508 extractParams (/*@null@*/ typeExpr te
)
5510 /* extract the parameters from a function header declarator's typeExpr */
5513 paramNodeList params
;
5514 lclTypeSpecNode paramtype
;
5515 pairNodeList head
= pairNodeList_new ();
5518 if (te
!= (typeExpr
) 0)
5520 params
= typeExpr_toParamNodeList (te
);
5521 if (paramNodeList_isDefined (params
))
5523 paramNodeList_elements (params
, param
)
5525 paramdecl
= param
->paramdecl
;
5526 paramtype
= param
->type
;
5527 if (paramdecl
!= (typeExpr
) 0 && paramtype
!= (lclTypeSpecNode
) 0)
5529 pair
= (pairNode
) dmalloc (sizeof (*pair
));
5530 sort
= lclTypeSpecNode2sort (paramtype
);
5531 /* 2/17/93, was sort_makeVal (sort) */
5532 sort
= sort_makeFormal (sort
);
5533 pair
->sort
= typeExpr2ptrSort (sort
, paramdecl
);
5534 /* pair->name = ltoken_getText (extractDeclarator (paramdecl)); */
5535 pair
->tok
= ltoken_copy (extractDeclarator (paramdecl
));
5536 pairNodeList_addh (head
, pair
);
5538 } end_paramNodeList_elements
;
5545 sigNode_rangeSort (sigNode sig
)
5547 if (sig
== (sigNode
) 0)
5549 return sort_makeNoSort ();
5553 return sort_fromLsymbol (ltoken_getText (sig
->range
));
5558 sigNode_domain (sigNode sig
)
5560 sortList domain
= sortList_new ();
5562 if (sig
== (sigNode
) 0)
5568 ltokenList dom
= sig
->domain
;
5570 ltokenList_elements (dom
, tok
)
5572 sortList_addh (domain
, sort_fromLsymbol (ltoken_getText (tok
)));
5573 } end_ltokenList_elements
;
5580 opFormUnion_createAnyOp (/*@temp@*/ ltoken t
)
5584 /* do not distinguish between .anyop and .id */
5590 opFormUnion_createMiddle (int middle
)
5599 markYieldParamNode (paramNode p
)
5603 llassert (p
->type
!= NULL
);
5604 p
->type
->quals
= qualList_add (p
->type
->quals
, qual_createYield ());
5609 /*@only@*/ lclTypeSpecNode
5610 lclTypeSpecNode_copySafe (lclTypeSpecNode n
)
5612 lclTypeSpecNode ret
= lclTypeSpecNode_copy (n
);
5614 llassert (ret
!= NULL
);
5618 /*@null@*/ /*@only@*/ lclTypeSpecNode
5619 lclTypeSpecNode_copy (/*@null@*/ lclTypeSpecNode n
)
5626 return (makeLclTypeSpecNodeConj (lclTypeSpecNode_copy (n
->content
.conj
->a
),
5627 lclTypeSpecNode_copy (n
->content
.conj
->b
)));
5629 return (makeLclTypeSpecNodeType (CTypesNode_copy (n
->content
.type
)));
5630 case LTS_STRUCTUNION
:
5631 return (makeLclTypeSpecNodeSU (strOrUnionNode_copy (n
->content
.structorunion
)));
5633 return (makeLclTypeSpecNodeEnum (enumSpecNode_copy (n
->content
.enumspec
)));
5640 void lclTypeSpecNode_free (/*@null@*/ /*@only@*/ lclTypeSpecNode n
)
5647 lclTypeSpecNode_free (n
->content
.conj
->a
);
5648 lclTypeSpecNode_free (n
->content
.conj
->b
);
5651 CTypesNode_free (n
->content
.type
);
5653 case LTS_STRUCTUNION
:
5654 strOrUnionNode_free (n
->content
.structorunion
);
5657 enumSpecNode_free (n
->content
.enumspec
);
5661 qualList_free (n
->quals
);
5666 static /*@null@*/ opFormNode
opFormNode_copy (/*@null@*/ opFormNode op
)
5670 opFormNode ret
= (opFormNode
) dmalloc (sizeof (*ret
));
5672 ret
->tok
= ltoken_copy (op
->tok
);
5673 ret
->kind
= op
->kind
;
5674 ret
->content
= op
->content
;
5676 ret
->close
= ltoken_copy (op
->close
);
5686 void opFormNode_free (/*@null@*/ opFormNode op
)
5690 ltoken_free (op
->tok
);
5691 ltoken_free (op
->close
);
5696 void nameNode_free (nameNode n
)
5703 opFormNode_free (n
->content
.opform
);
5711 lslOp_equal (lslOp x
, lslOp y
)
5714 ((x
!= 0) && (y
!= 0) &&
5715 sameNameNode (x
->name
, y
->name
) &&
5716 sigNode_equal (x
->signature
, y
->signature
)));
5719 void lslOp_free (lslOp x
)
5721 nameNode_free (x
->name
);
5725 void sigNode_free (sigNode x
)
5729 ltokenList_free (x
->domain
);
5730 ltoken_free (x
->tok
);
5731 ltoken_free (x
->range
);
5736 void declaratorNode_free (/*@null@*/ /*@only@*/ declaratorNode x
)
5740 typeExpr_free (x
->type
);
5741 ltoken_free (x
->id
);
5746 void abstBodyNode_free (/*@null@*/ /*@only@*/ abstBodyNode n
)
5750 lclPredicateNode_free (n
->typeinv
);
5751 fcnNodeList_free (n
->fcns
);
5752 ltoken_free (n
->tok
);
5757 void fcnNode_free (/*@null@*/ /*@only@*/ fcnNode f
)
5761 lclTypeSpecNode_free (f
->typespec
);
5762 declaratorNode_free (f
->declarator
);
5763 globalList_free (f
->globals
);
5764 varDeclarationNodeList_free (f
->inits
);
5765 letDeclNodeList_free (f
->lets
);
5766 lclPredicateNode_free (f
->checks
);
5767 lclPredicateNode_free (f
->require
);
5768 lclPredicateNode_free (f
->claim
);
5769 lclPredicateNode_free (f
->ensures
);
5770 modifyNode_free (f
->modify
);
5771 ltoken_free (f
->name
);
5776 void declaratorInvNode_free (/*@null@*/ /*@only@*/ declaratorInvNode x
)
5780 declaratorNode_free (x
->declarator
);
5781 abstBodyNode_free (x
->body
);
5786 /*@only@*/ lslOp
lslOp_copy (lslOp x
)
5788 return (makelslOpNode (nameNode_copy (x
->name
), x
->signature
));
5791 sigNode
sigNode_copy (sigNode s
)
5793 llassert (s
!= NULL
);
5794 return (makesigNode (ltoken_copy (s
->tok
),
5795 ltokenList_copy (s
->domain
),
5796 ltoken_copy (s
->range
)));
5799 /*@null@*/ nameNode
nameNode_copy (/*@null@*/ nameNode n
)
5801 if (n
== NULL
) return NULL
;
5802 return nameNode_copySafe (n
);
5805 nameNode
nameNode_copySafe (nameNode n
)
5809 return (makeNameNodeId (ltoken_copy (n
->content
.opid
)));
5813 /* error should be detected by splint: forgot to copy opform! */
5814 return (makeNameNodeForm (opFormNode_copy (n
->content
.opform
)));
5818 bool initDeclNode_isRedeclaration (initDeclNode d
)
5820 return (d
->declarator
->isRedecl
);
5823 void termNode_free (/*@only@*/ /*@null@*/ termNode t
)
5827 sortSet_free (t
->possibleSorts
);
5828 lslOpSet_free (t
->possibleOps
);
5829 nameNode_free (t
->name
);
5830 termNodeList_free (t
->args
);
5835 /*@only@*/ termNode
termNode_copySafe (termNode t
)
5837 termNode ret
= termNode_copy (t
);
5839 llassert (ret
!= NULL
);
5843 /*@null@*/ /*@only@*/ termNode
termNode_copy (/*@null@*/ termNode t
)
5847 termNode ret
= (termNode
) dmalloc (sizeof (*ret
));
5849 ret
->wrapped
= t
->wrapped
;
5850 ret
->kind
= t
->kind
;
5851 ret
->sort
= t
->sort
;
5852 ret
->given
= t
->given
;
5853 ret
->possibleSorts
= sortSet_copy (t
->possibleSorts
);
5854 ret
->error_reported
= t
->error_reported
;
5855 ret
->possibleOps
= lslOpSet_copy (t
->possibleOps
);
5856 ret
->name
= nameNode_copy (t
->name
);
5857 ret
->args
= termNodeList_copy (t
->args
);
5859 if (t
->kind
== TRM_LITERAL
5860 || t
->kind
== TRM_SIZEOF
5861 || t
->kind
== TRM_VAR
5862 || t
->kind
== TRM_CONST
5863 || t
->kind
== TRM_ZEROARY
)
5865 ret
->literal
= ltoken_copy (t
->literal
);
5868 if (t
->kind
== TRM_UNCHANGEDOTHERS
)
5870 ret
->unchanged
= storeRefNodeList_copy (t
->unchanged
);
5873 if (t
->kind
== TRM_QUANTIFIER
)
5875 ret
->quantified
= quantifiedTermNode_copy (t
->quantified
);
5878 if (t
->kind
== TRM_SIZEOF
)
5880 ret
->sizeofField
= lclTypeSpecNode_copySafe (t
->sizeofField
);
5892 void importNode_free (/*@only@*/ /*@null@*/ importNode x
)
5896 ltoken_free (x
->val
);
5901 void initDeclNode_free (/*@only@*/ /*@null@*/ initDeclNode x
)
5905 declaratorNode_free (x
->declarator
);
5906 termNode_free (x
->value
);
5911 void letDeclNode_free (/*@only@*/ /*@null@*/ letDeclNode x
)
5915 lclTypeSpecNode_free (x
->sortspec
);
5916 termNode_free (x
->term
);
5917 ltoken_free (x
->varid
);
5922 void pairNode_free (/*@only@*/ /*@null@*/ pairNode x
)
5926 ltoken_free (x
->tok
);
5931 /*@null@*/ paramNode
paramNode_copy (/*@null@*/ paramNode p
)
5935 paramNode ret
= (paramNode
) dmalloc (sizeof (*ret
));
5937 ret
->type
= lclTypeSpecNode_copy (p
->type
);
5938 ret
->paramdecl
= typeExpr_copy (p
->paramdecl
);
5939 ret
->kind
= p
->kind
;
5946 void paramNode_free (/*@only@*/ /*@null@*/ paramNode x
)
5950 lclTypeSpecNode_free (x
->type
);
5951 typeExpr_free (x
->paramdecl
);
5956 void programNode_free (/*@only@*/ /*@null@*/ programNode x
)
5962 case ACT_SELF
: stmtNode_free (x
->content
.self
); break;
5965 case ACT_SEQUENCE
: programNodeList_free (x
->content
.args
); break;
5972 quantifierNode
quantifierNode_copy (quantifierNode x
)
5974 quantifierNode ret
= (quantifierNode
) dmalloc (sizeof (*ret
));
5976 ret
->quant
= ltoken_copy (x
->quant
);
5977 ret
->vars
= varNodeList_copy (x
->vars
);
5978 ret
->isForall
= x
->isForall
;
5984 void quantifierNode_free (/*@null@*/ /*@only@*/ quantifierNode x
)
5988 varNodeList_free (x
->vars
);
5989 ltoken_free (x
->quant
);
5993 # endif /* DEADCODE */
5995 void replaceNode_free (/*@only@*/ /*@null@*/ replaceNode x
)
6005 nameNode_free (x
->content
.renamesortname
.name
);
6006 sigNode_free (x
->content
.renamesortname
.signature
);
6009 typeNameNode_free (x
->typename
);
6010 ltoken_free (x
->tok
);
6015 storeRefNode
storeRefNode_copy (storeRefNode x
)
6017 storeRefNode ret
= (storeRefNode
) dmalloc (sizeof (*ret
));
6019 ret
->kind
= x
->kind
;
6024 ret
->content
.term
= termNode_copySafe (x
->content
.term
);
6026 case SRN_OBJ
: case SRN_TYPE
:
6027 ret
->content
.type
= lclTypeSpecNode_copy (x
->content
.type
);
6030 ret
->content
.ref
= sRef_copy (x
->content
.ref
);
6037 void storeRefNode_free (/*@only@*/ /*@null@*/ storeRefNode x
)
6041 if (storeRefNode_isTerm (x
))
6043 termNode_free (x
->content
.term
);
6045 else if (storeRefNode_isType (x
) || storeRefNode_isObj (x
))
6047 lclTypeSpecNode_free (x
->content
.type
);
6051 /* nothing to free */
6058 stDeclNode
stDeclNode_copy (stDeclNode x
)
6060 stDeclNode ret
= (stDeclNode
) dmalloc (sizeof (*ret
));
6062 ret
->lcltypespec
= lclTypeSpecNode_copySafe (x
->lcltypespec
);
6063 ret
->declarators
= declaratorNodeList_copy (x
->declarators
);
6068 void stDeclNode_free (/*@only@*/ /*@null@*/ stDeclNode x
)
6072 lclTypeSpecNode_free (x
->lcltypespec
);
6073 declaratorNodeList_free (x
->declarators
);
6078 void traitRefNode_free (/*@only@*/ /*@null@*/ traitRefNode x
)
6082 ltokenList_free (x
->traitid
);
6083 renamingNode_free (x
->rename
);
6088 void typeNameNode_free (/*@only@*/ /*@null@*/ typeNameNode n
)
6092 typeNamePack_free (n
->typename
);
6093 opFormNode_free (n
->opform
);
6098 void varDeclarationNode_free (/*@only@*/ /*@null@*/ varDeclarationNode x
)
6108 lclTypeSpecNode_free (x
->type
);
6109 initDeclNodeList_free (x
->decls
);
6115 varNode
varNode_copy (varNode x
)
6117 varNode ret
= (varNode
) dmalloc (sizeof (*ret
));
6119 ret
->varid
= ltoken_copy (x
->varid
);
6120 ret
->isObj
= x
->isObj
;
6121 ret
->type
= lclTypeSpecNode_copySafe (x
->type
);
6122 ret
->sort
= x
->sort
;
6128 void varNode_free (/*@only@*/ /*@null@*/ varNode x
)
6132 lclTypeSpecNode_free (x
->type
);
6133 ltoken_free (x
->varid
);
6137 # endif /* DEADCODE */
6139 void stmtNode_free (/*@only@*/ /*@null@*/ stmtNode x
)
6143 ltoken_free (x
->lhs
);
6144 termNodeList_free (x
->args
);
6145 ltoken_free (x
->operator);
6150 void renamingNode_free (/*@only@*/ /*@null@*/ renamingNode x
)
6156 replaceNodeList_free (x
->content
.replace
);
6160 nameAndReplaceNode_free (x
->content
.name
);
6167 void nameAndReplaceNode_free (/*@only@*/ /*@null@*/ nameAndReplaceNode x
)
6171 typeNameNodeList_free (x
->namelist
);
6172 replaceNodeList_free (x
->replacelist
);
6177 void typeNamePack_free (/*@only@*/ /*@null@*/ typeNamePack x
)
6181 lclTypeSpecNode_free (x
->type
);
6182 abstDeclaratorNode_free (x
->abst
);
6188 cstring
interfaceNode_unparse (interfaceNode x
)
6195 return (message ("[imports] %q", importNodeList_unparse (x
->content
.imports
)));
6197 return (message ("[uses] %q", traitRefNodeList_unparse (x
->content
.uses
)));
6199 return (message ("[export] %q", exportNode_unparse (x
->content
.export
)));
6201 return (message ("[private] %q", privateNode_unparse (x
->content
.private)));
6208 return (cstring_makeLiteral ("<interface node undefined>"));
6211 BADBRANCHRET (cstring_undefined
);
6213 # endif /* DEADCODE */
6215 void interfaceNode_free (/*@null@*/ /*@only@*/ interfaceNode x
)
6222 case INF_IMPORTS
: importNodeList_free (x
->content
.imports
); break;
6223 case INF_USES
: traitRefNodeList_free (x
->content
.uses
); break;
6224 case INF_EXPORT
: exportNode_free (x
->content
.export
); break;
6225 case INF_PRIVATE
: privateNode_free (x
->content
.private); break;
6231 void exportNode_free (/*@null@*/ /*@only@*/ exportNode x
)
6237 case XPK_CONST
: constDeclarationNode_free (x
->content
.constdeclaration
); break;
6238 case XPK_VAR
: varDeclarationNode_free (x
->content
.vardeclaration
); break;
6239 case XPK_TYPE
: typeNode_free (x
->content
.type
); break;
6240 case XPK_FCN
: fcnNode_free (x
->content
.fcn
); break;
6241 case XPK_CLAIM
: claimNode_free (x
->content
.claim
); break;
6242 case XPK_ITER
: iterNode_free (x
->content
.iter
); break;
6249 void privateNode_free (/*@null@*/ /*@only@*/ privateNode x
)
6256 constDeclarationNode_free (x
->content
.constdeclaration
); break;
6258 varDeclarationNode_free (x
->content
.vardeclaration
); break;
6260 typeNode_free (x
->content
.type
); break;
6262 fcnNode_free (x
->content
.fcn
); break;
6269 void constDeclarationNode_free (/*@only@*/ /*@null@*/ constDeclarationNode x
)
6273 lclTypeSpecNode_free (x
->type
);
6274 initDeclNodeList_free (x
->decls
);
6279 void typeNode_free (/*@only@*/ /*@null@*/ typeNode t
)
6285 case TK_ABSTRACT
: abstractNode_free (t
->content
.abstract
); break;
6286 case TK_EXPOSED
: exposedNode_free (t
->content
.exposed
); break;
6287 case TK_UNION
: taggedUnionNode_free (t
->content
.taggedunion
); break;
6294 void claimNode_free (/*@only@*/ /*@null@*/ claimNode x
)
6298 paramNodeList_free (x
->params
);
6299 globalList_free (x
->globals
);
6300 letDeclNodeList_free (x
->lets
);
6301 lclPredicateNode_free (x
->require
);
6302 programNode_free (x
->body
);
6303 lclPredicateNode_free (x
->ensures
);
6304 ltoken_free (x
->name
);
6309 void iterNode_free (/*@only@*/ /*@null@*/ iterNode x
)
6313 paramNodeList_free (x
->params
);
6314 ltoken_free (x
->name
);
6319 void abstractNode_free (/*@only@*/ /*@null@*/ abstractNode x
)
6323 abstBodyNode_free (x
->body
);
6324 ltoken_free (x
->tok
);
6325 ltoken_free (x
->name
);
6330 void exposedNode_free (/*@only@*/ /*@null@*/ exposedNode x
)
6334 lclTypeSpecNode_free (x
->type
);
6335 declaratorInvNodeList_free (x
->decls
);
6336 ltoken_free (x
->tok
);
6341 void taggedUnionNode_free (/*@only@*/ /*@null@*/ taggedUnionNode x
)
6345 stDeclNodeList_free (x
->structdecls
);
6346 declaratorNode_free (x
->declarator
);
6351 /*@only@*/ /*@null@*/ strOrUnionNode
6352 strOrUnionNode_copy (/*@null@*/ strOrUnionNode n
)
6356 strOrUnionNode ret
= (strOrUnionNode
) dmalloc (sizeof (*ret
));
6358 ret
->kind
= n
->kind
;
6359 ret
->tok
= ltoken_copy (n
->tok
);
6360 ret
->opttagid
= ltoken_copy (n
->opttagid
);
6361 ret
->sort
= n
->sort
;
6362 ret
->structdecls
= stDeclNodeList_copy (n
->structdecls
);
6372 void strOrUnionNode_free (/*@null@*/ /*@only@*/ strOrUnionNode n
)
6376 stDeclNodeList_free (n
->structdecls
);
6377 ltoken_free (n
->tok
);
6378 ltoken_free (n
->opttagid
);
6383 void enumSpecNode_free (/*@null@*/ /*@only@*/ enumSpecNode x
)
6387 ltokenList_free (x
->enums
);
6388 ltoken_free (x
->tok
);
6389 ltoken_free (x
->opttagid
);
6394 /*@only@*/ /*@null@*/ enumSpecNode
enumSpecNode_copy (/*@null@*/ enumSpecNode x
)
6398 enumSpecNode ret
= (enumSpecNode
) dmalloc (sizeof (*ret
));
6400 ret
->tok
= ltoken_copy (x
->tok
);
6401 ret
->opttagid
= ltoken_copy (x
->opttagid
);
6402 ret
->enums
= ltokenList_copy (x
->enums
);
6403 ret
->sort
= x
->sort
;
6413 void lsymbol_setbool (lsymbol s
)
6418 lsymbol
lsymbol_getbool (void)
6420 return lsymbol_bool
;
6423 lsymbol
lsymbol_getBool (void)
6425 return lsymbol_Bool
;
6428 lsymbol
lsymbol_getFALSE (void)
6430 return lsymbol_FALSE
;
6433 lsymbol
lsymbol_getTRUE (void)
6435 return lsymbol_TRUE
;