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 ** Symbol table abstraction
31 ** Gary Feldman, Technical Languages and Environments, DECspec project
33 ** Massachusetts Institute of Technology
34 ** Joe Wild, Technical Languages and Environments, DECspec project
36 ** Massachusetts Institute of Technology
43 # include "splintMacros.nf"
45 # include "lslparse.h"
46 # include "lclsyntable.h"
47 # include "llgrammar.h"
51 static bool isBlankLine (char *p_line
);
52 static bool inImport
= FALSE
;
54 /*@constant static int MAXBUFFLEN;@*/
55 # define MAXBUFFLEN 512
56 /*@constant static int DELTA;@*/
59 static void symHashTable_dump (symHashTable
* p_t
, FILE * p_f
, bool p_lco
);
61 static void tagInfo_free (/*@only@*/ tagInfo p_tag
);
62 static /*@observer@*/ scopeInfo
symtable_scopeInfo (symtable p_stable
);
64 static void symtable_dumpId (symtable p_stable
, FILE *p_f
, bool p_lco
);
65 static lsymbol
nameNode2key (nameNode p_n
);
69 SYMK_FCN
, SYMK_SCOPE
, SYMK_TYPE
, SYMK_VAR
77 /*@only@*/ fctInfo fct
;
78 /*@only@*/ scopeInfo scope
;
79 /*@only@*/ typeInfo type
;
80 /*@only@*/ varInfo var
;
87 unsigned int allocated
;
88 /*@relnull@*/ idTableEntry
*entries
;
92 struct s_symtableStruct
94 idTable
*idTable
; /* data is idTableEntry */
95 symHashTable
*hTable
; /* data is htData */
96 mapping type2sort
; /* maps LCL type symbol to LSL sort */
99 static /*@observer@*/ ltoken
idTableEntry_getId (idTableEntry
*p_x
);
100 static /*@out@*/ /*@exposed@*/ idTableEntry
*nextFree (idTable
* p_st
);
101 static /*@dependent@*/ /*@null@*/ idTableEntry
*symtable_lookup (idTable
* p_st
, lsymbol p_id
);
102 static /*@dependent@*/ /*@null@*/ idTableEntry
*symtable_lookupInScope (idTable
* p_st
, lsymbol p_id
);
104 static /*@only@*/ idTable
*symtable_newIdTable (void);
105 static void idTableEntry_free (idTableEntry p_x
);
107 /* Local implementatio of hash table */
109 static bool allowed_redeclaration
= FALSE
;
110 static symbolKey
htData_key (htData
*p_x
);
112 static void symHashTable_free (/*@only@*/ symHashTable
*p_h
);
113 static /*@only@*/ symHashTable
*symHashTable_create (unsigned int p_size
);
114 static /*@null@*/ /*@exposed@*/ htData
*
115 symHashTable_get (symHashTable
* p_t
, symbolKey p_key
, infoKind p_kind
,
116 /*@null@*/ nameNode p_n
);
117 static bool symHashTable_put (symHashTable
*p_t
, /*@only@*/ htData
*p_data
);
118 static /*@only@*/ /*@exposed@*/ /*@null@*/ htData
*
119 symHashTable_forcePut (symHashTable
* p_t
, /*@only@*/ htData
*p_data
);
120 /* static unsigned int symHashTable_count (symHashTable * t); */
122 static void idTable_free (/*@only@*/ idTable
*p_st
);
124 void varInfo_free (/*@only@*/ varInfo v
)
130 static /*@only@*/ varInfo
varInfo_copy (varInfo v
)
132 varInfo ret
= (varInfo
) dmalloc (sizeof (*ret
));
134 ret
->id
= ltoken_copy (v
->id
);
137 ret
->export
= v
->export
;
142 void symtable_free (symtable stable
)
145 symtable_printStats (stable
);
148 idTable_free (stable
->idTable
);
149 symHashTable_free (stable
->hTable
);
150 mapping_free (stable
->type2sort
);
154 static void idTable_free (idTable
*st
)
158 for (i
= 0; i
< st
->size
; i
++)
160 idTableEntry_free (st
->entries
[i
]);
167 static void fctInfo_free (/*@only@*/ fctInfo f
)
169 signNode_free (f
->signature
);
170 pairNodeList_free (f
->globals
);
175 static void typeInfo_free (/*@only@*/ typeInfo t
)
181 static void scopeInfo_free (/*@only@*/ scopeInfo s
)
186 static void idTableEntry_free (idTableEntry x
)
191 fctInfo_free (x
.info
.fct
);
194 scopeInfo_free (x
.info
.scope
);
197 typeInfo_free (x
.info
.type
);
200 varInfo_free (x
.info
.var
);
205 static /*@observer@*/ ltoken
idTableEntry_getId (idTableEntry
*x
)
210 return (x
->info
.fct
->id
);
212 return ltoken_undefined
;
214 return (x
->info
.type
->id
);
216 return (x
->info
.var
->id
);
219 BADBRANCHRET (ltoken_undefined
);
225 symtable stable
= (symtable
) dmalloc (sizeof (*stable
));
228 stable
->idTable
= symtable_newIdTable ();
229 stable
->hTable
= symHashTable_create (HT_MAXINDEX
);
230 stable
->type2sort
= mapping_create ();
232 /* add builtin synonym: Bool -> bool */
234 mapping_bind (stable
->type2sort
, lsymbol_getBool (), lsymbol_getbool ());
237 ** done by symtable_newIdTable
238 ** st->allocated = 0;
239 ** st->entries = (idTableEntry *) 0;
240 ** st->exporting = TRUE;
243 /* this is global scope */
244 e
= nextFree (stable
->idTable
);
245 e
->kind
= SYMK_SCOPE
;
246 (e
->info
).scope
= (scopeInfo
) dmalloc (sizeof (*((e
->info
).scope
)));
247 (e
->info
).scope
->kind
= SPE_GLOBAL
;
252 static /*@only@*/ idTable
*symtable_newIdTable (void)
254 idTable
*st
= (idTable
*) dmalloc (sizeof (*st
));
258 st
->entries
= (idTableEntry
*) 0;
259 st
->exporting
= TRUE
;
261 /* this was being done twice!
263 e->kind = SYMK_SCOPE;
264 (e->info).scope.kind = globScope;
271 nameNode2key (nameNode n
)
277 ret
= ltoken_getText (n
->content
.opid
);
281 /* use opForm's key as its Identifier */
282 llassert (n
->content
.opform
!= NULL
);
283 ret
= (n
->content
.opform
)->key
;
290 ** requires: nameNode n is already in st.
294 htData_insertSignature (htData
*d
, /*@owned@*/ sigNode oi
)
296 sigNodeSet set
= d
->content
.op
->signatures
;
299 if (oi
!= (sigNode
) 0)
301 return (sigNodeSet_insert (set
, oi
));
307 symtable_enterOp (symtable st
, /*@only@*/ /*@notnull@*/ nameNode n
,
308 /*@owned@*/ sigNode oi
)
311 ** Operators are overloaded, we allow entering opInfo more than once,
312 ** even if it's the same signature.
314 ** Assumes all sorts are already entered into the symbol table
317 symHashTable
*ht
= st
->hTable
;
323 id
= nameNode2key (n
);
325 d
= symHashTable_get (ht
, id
, IK_OP
, n
);
327 if (d
== (htData
*) 0)
328 { /* first signature of this operator */
329 opInfo op
= (opInfo
) dmalloc (sizeof (*op
));
330 htData
*nd
= (htData
*) dmalloc (sizeof (*nd
));
334 if (oi
!= (sigNode
) 0)
336 op
->signatures
= sigNodeSet_singleton (oi
);
341 op
->signatures
= sigNodeSet_new ();
342 sigNode_markOwned (oi
);
347 (void) symHashTable_put (ht
, nd
);
352 nameNode_free (n
); /*<<<??? */
354 if (htData_insertSignature (d
, oi
))
362 symtable_enterTag (symtable st
, tagInfo ti
)
364 /* put ti only if it is not already in symtable */
365 symHashTable
*ht
= st
->hTable
;
367 symbolKey key
= ltoken_getText (ti
->id
);
369 d
= symHashTable_get (ht
, key
, IK_TAG
, (nameNode
) 0);
370 if (d
== (htData
*) 0)
372 d
= (htData
*) dmalloc (sizeof (*d
));
375 d
->content
.tag
->imported
= context_inImport ();
376 (void) symHashTable_put (ht
, d
);
381 if (d
->content
.tag
->imported
)
384 d
->content
.tag
->imported
= context_inImport ();
396 symtable_enterTagForce (symtable st
, tagInfo ti
)
398 /* put ti, force-put if necessary */
399 symHashTable
*ht
= st
->hTable
;
401 symbolKey key
= ltoken_getText (ti
->id
);
403 d
= symHashTable_get (ht
, key
, IK_TAG
, (nameNode
) 0);
405 if (d
== (htData
*) 0)
407 d
= (htData
*) dmalloc (sizeof (*d
));
411 d
->content
.tag
->imported
= context_inImport ();
412 (void) symHashTable_put (ht
, d
);
420 d
->content
.tag
->imported
= context_inImport ();
421 /* interpret return data later, htData * */
422 /*@i@*/ (void) symHashTable_forcePut (ht
, d
);
428 symtable_opInfo (symtable st
, /*@notnull@*/ nameNode n
)
430 symHashTable
*ht
= st
->hTable
;
431 lsymbol i
= nameNode2key (n
);
434 d
= symHashTable_get (ht
, i
, IK_OP
, n
);
435 if (d
== (htData
*) 0)
440 return (d
->content
.op
);
444 symtable_tagInfo (symtable st
, lsymbol i
)
446 symHashTable
*ht
= st
->hTable
;
448 d
= symHashTable_get (ht
, i
, IK_TAG
, 0);
450 if (d
== (htData
*) 0)
452 return (tagInfo
) NULL
;
455 return (d
->content
.tag
);
459 symtable_enterScope (symtable stable
, scopeInfo si
)
461 idTable
*st
= stable
->idTable
;
462 idTableEntry
*e
= nextFree (st
);
463 if (si
->kind
== SPE_GLOBAL
)
464 llbuglit ("symtable_enterScope: SPE_GLOBAL");
465 e
->kind
= SYMK_SCOPE
;
466 (e
->info
).scope
= si
;
470 symtable_exitScope (symtable stable
)
472 idTable
*st
= stable
->idTable
;
475 if (st
->entries
!= NULL
)
477 for (n
= st
->size
- 1; (st
->entries
[n
]).kind
!= SYMK_SCOPE
; n
--)
484 llcontbuglit ("symtable_exitScope: no scope to exit");
492 symtable_enterFct (symtable stable
, fctInfo fi
)
494 idTable
*st
= stable
->idTable
;
498 if (!allowed_redeclaration
&&
499 symtable_lookup (st
, ltoken_getText (fi
->id
)) != (idTableEntry
*) 0)
501 lclRedeclarationError (fi
->id
);
507 fi
->export
= st
->exporting
; /* && !fi->private; */
514 symtable_enterType (symtable stable
, /*@only@*/ typeInfo ti
)
516 idTable
*st
= stable
->idTable
;
519 scopeKind k
= (symtable_scopeInfo (stable
))->kind
;
521 /* symtable_disp (stable); */
523 if (k
!= SPE_GLOBAL
&& k
!= SPE_INVALID
) /* fixed for Splint */
525 llbug (message ("%q: symtable_enterType: expect global scope. (type: %s)",
526 ltoken_unparseLoc (ti
->id
),
527 ltoken_getRawString (ti
->id
)));
530 if (!allowed_redeclaration
&&
531 symtable_lookup (st
, ltoken_getText (ti
->id
)) != (idTableEntry
*) 0)
533 /* ignore if Bool is re-entered */
534 if (ltoken_getText (ti
->id
) == lsymbol_getBool () ||
535 ltoken_getText (ti
->id
) == lsymbol_getbool ())
541 lclRedeclarationError (ti
->id
);
546 /* make sure it is a type TYPEDEF_NAME; */
548 if (ltoken_getCode (ti
->id
) != LLT_TYPEDEF_NAME
)
550 lclbug (message ("symtable_enterType: gets a simpleId, expect a type: %s",
551 ltoken_getRawString (ti
->id
)));
556 ti
->export
= st
->exporting
;/* && !ti->private; */
558 mapping_bind (stable
->type2sort
, ltoken_getText (ti
->id
),
559 sort_getLsymbol (sort_makeVal (sort_getUnderlying (ti
->basedOn
))));
568 lsymbol_sortFromType (symtable s
, lsymbol typename
)
573 /* check the synonym table first */
574 if (LCLIsSyn (typename
))
576 tok
= LCLGetTokenForSyn (typename
);
577 inter
= ltoken_getText (tok
);
578 /* printf ("In lsymbol_sortFromType: %s -> %s\n",
579 lsymbol_toChars (typename), lsymbol_toChars (inter)); */
586 /* now map LCL type to sort */
587 out
= mapping_find (s
->type2sort
, inter
);
589 if (out
== lsymbol_undefined
)
600 ** returns true is vi is a redeclaration
604 symtable_enterVar (symtable stable
, /*@temp@*/ varInfo vi
)
606 idTable
*st
= stable
->idTable
;
611 /* symtable_disp (symtab); */
613 if (!allowed_redeclaration
&&
614 (symtable_lookupInScope (st
, ltoken_getText (vi
->id
)) != (idTableEntry
*) 0))
616 if (ltoken_getText (vi
->id
) == lsymbol_getTRUE () ||
617 ltoken_getText (vi
->id
) == lsymbol_getFALSE ())
623 if (usymtab_existsEither (ltoken_getRawString (vi
->id
)))
625 lclRedeclarationError (vi
->id
);
630 llbuglit ("redeclared somethingerother?!");
637 idTableEntry
*e
= nextFree (st
);
640 vi
->export
= st
->exporting
&& /* !vi.private && */
641 (vi
->kind
== VRK_VAR
|| vi
->kind
== VRK_CONST
|| vi
->kind
== VRK_ENUM
);
642 (e
->info
).var
= varInfo_copy (vi
);
649 symtable_exists (symtable stable
, lsymbol i
)
651 idTable
*st
= stable
->idTable
;
652 return symtable_lookup (st
, i
) != (idTableEntry
*) 0;
656 symtable_typeInfo (symtable stable
, lsymbol i
)
661 st
= stable
->idTable
;
662 e
= symtable_lookup (st
, i
);
664 if (e
== (idTableEntry
*) 0 || e
->kind
!= SYMK_TYPE
)
666 return (typeInfo
) NULL
;
669 return (e
->info
).type
;
673 symtable_varInfo (symtable stable
, lsymbol i
)
675 idTable
*st
= stable
->idTable
;
678 e
= symtable_lookup (st
, i
);
680 if (e
== (idTableEntry
*) 0 || e
->kind
!= SYMK_VAR
)
682 return (varInfo
) NULL
;
685 return (e
->info
).var
;
689 symtable_varInfoInScope (symtable stable
, lsymbol id
)
691 /* if current scope is a SPE_QUANT, can go beyond current scope */
692 idTable
*st
= stable
->idTable
;
693 idTableEntry
*e2
= (idTableEntry
*) 0;
696 for (n
= st
->size
- 1; n
>= 0; n
--)
700 e2
= &(st
->entries
[n
]);
702 if (e2
->kind
== SYMK_SCOPE
&& e2
->info
.scope
->kind
!= SPE_QUANT
)
704 return (varInfo
) NULL
;
707 tok
= idTableEntry_getId (e2
);
709 if (e2
->kind
== SYMK_VAR
&& ltoken_getText (tok
) == id
)
711 return (e2
->info
).var
;
715 return (varInfo
) NULL
;
719 symtable_scopeInfo (symtable stable
)
721 idTable
*st
= stable
->idTable
;
725 for (n
= st
->size
- 1; n
>= 0; n
--)
727 e
= &(st
->entries
[n
]);
728 if (e
->kind
== SYMK_SCOPE
)
729 return (e
->info
).scope
;
732 lclfatalbug ("symtable_scopeInfo: not found");
737 symtable_export (symtable stable
, bool yesNo
)
739 idTable
*st
= stable
->idTable
;
740 st
->exporting
= yesNo
;
741 (void) sort_setExporting (yesNo
);
745 symHashTable_dump (symHashTable
* t
, FILE * f
, bool lco
)
747 /* like symHashTable_dump2 but for output to .lcs file */
755 for (i
= 0; i
<= HT_MAXINDEX
; i
++)
759 for (entry
= b
; entry
!= NULL
; entry
= entry
->next
)
766 /*@switchbreak@*/ break;
769 char *name
= cstring_toCharsSafe (nameNode_unparse (d
->content
.op
->name
));
770 sigs
= d
->content
.op
->signatures
;
772 sigNodeSet_elements (sigs
, x
)
774 cstring s
= sigNode_unparse (x
);
778 fprintf (f
, "%%LCL");
781 fprintf (f
, "op %s %s\n", name
, cstring_toCharsSafe (s
));
783 } end_sigNodeSet_elements
;
786 /*@switchbreak@*/ break;
789 tok
= d
->content
.tag
->id
;
791 if (!ltoken_isUndefined (tok
))
793 cstring s
= tagKind_unparse (d
->content
.tag
->kind
);
797 fprintf (f
, "%%LCL");
800 fprintf (f
, "tag %s %s\n", ltoken_getTextChars (tok
),
801 cstring_toCharsSafe (s
));
804 /*@switchbreak@*/ break;
811 symtable_dump (symtable stable
, FILE * f
, bool lco
)
813 symHashTable
*ht
= stable
->hTable
;
816 fprintf (f
, "%s\n", BEGINSYMTABLE
);
818 symHashTable_dump (ht
, f
, lco
);
820 symtable_dumpId (stable
, f
, lco
);
822 fprintf (f
, "%s\n", SYMTABLEEND
);
826 lsymbol_translateSort (mapping m
, lsymbol s
)
828 lsymbol res
= mapping_find (m
, s
);
829 if (res
== lsymbol_undefined
)
834 static /*@null@*/ lslOp
835 lslOp_renameSorts (mapping map
,/*@returned@*/ /*@null@*/ lslOp op
)
844 sign
= op
->signature
;
846 domain
= sign
->domain
;
848 ltokenList_elements (domain
, dt
)
851 lsymbol_translateSort (map
, ltoken_getText (dt
)));
852 } end_ltokenList_elements
;
854 /*@-onlytrans@*/ /* A memory leak... */
855 op
->signature
= makesigNode (sign
->tok
, domain
, range
);
862 static /*@null@*/ signNode
863 signNode_fromsigNode (sigNode s
)
868 if (s
== (sigNode
) 0)
873 sign
= (signNode
) dmalloc (sizeof (*sign
));
874 slist
= sortList_new ();
875 sign
->tok
= ltoken_copy (s
->tok
);
877 sign
->range
= sort_makeSort (ltoken_undefined
, ltoken_getText (s
->range
));
879 ltokenList_elements (s
->domain
, dt
)
881 sortList_addh (slist
, sort_makeSort (ltoken_undefined
, ltoken_getText (dt
)));
882 } end_ltokenList_elements
;
884 sign
->domain
= slist
;
889 /** 2.4.3 ymtan 93.09.23 -- fixed bug in parseGlobals: removed ";" at the
890 ** end of pairNode (gstr).
893 static /*@only@*/ pairNodeList
894 parseGlobals (char *line
, inputStream srce
)
896 pairNodeList plist
= pairNodeList_new ();
899 char *lineptr
, sostr
[MAXBUFFLEN
], gstr
[MAXBUFFLEN
];
901 /* line is not all blank */
902 /* expected format: "sort1 g1; sort2 g2; sort3 g3;" */
905 while (!isBlankLine (lineptr
))
907 if (sscanf (lineptr
, "%s %s", &(sostr
[0]), gstr
) != 2)
911 ("%q: Imported file contains illegal function global declaration.\n"
912 "Skipping rest of the line: %s (%s)",
913 fileloc_unparseRaw (inputStream_fileName (srce
),
914 inputStream_thisLineNumber (srce
)),
915 cstring_fromChars (line
),
916 cstring_fromChars (lineptr
)));
920 p
= (pairNode
) dmalloc (sizeof (*p
));
922 /* Note: remove the ";" separator at the end of gstr */
923 semi_index
= size_toInt (strlen (gstr
));
924 gstr
[semi_index
- 1] = '\0';
926 p
->tok
= ltoken_create (NOTTOKEN
, lsymbol_fromChars (gstr
));
927 p
->sort
= sort_makeSort (ltoken_undefined
, lsymbol_fromChars (sostr
));
929 pairNodeList_addh (plist
, p
);
930 lineptr
= strchr (lineptr
, ';'); /* go pass the next; */
932 llassert (lineptr
!= NULL
);
933 lineptr
= lineptr
+ 1;
940 isBlankLine (char *line
)
944 if (line
== NULL
) return TRUE
;
946 for (i
= 0; line
[i
] != '\0'; i
++)
959 typedef /*@only@*/ fctInfo o_fctInfo
;
962 parseLine (char *line
, inputStream srce
, mapping map
)
964 static /*@owned@*/ o_fctInfo
*savedFcn
= NULL
;
965 char *lineptr
, *lineptr2
;
966 cstring importfile
= inputStream_fileName (srce
);
967 char namestr
[MAXBUFFLEN
], kstr
[20], sostr
[MAXBUFFLEN
];
968 sort bsort
, nullSort
= sort_makeNoSort ();
970 fileloc imploc
= fileloc_undefined
;
975 imploc
= fileloc_createImport (importfile
, inputStream_thisLineNumber (srce
));
978 if (firstWord (line
, "op"))
982 lineptr
= strchr (line
, 'o'); /* remove any leading blanks */
983 llassert (lineptr
!= NULL
);
984 lineptr
= strchr (lineptr
, ' '); /* go past "op" */
985 llassert (lineptr
!= NULL
);
987 /* add a newline to the end of the line since parseOpLine expects it */
988 lineptr2
= strchr (lineptr
, '\0');
993 *(lineptr2
+ 1) = '\0';
996 llassert (cstring_isDefined (importfile
));
997 op
= parseOpLine (importfile
, cstring_fromChars (lineptr
+ 1));
1003 ("%q: Imported file contains illegal operator declaration:\n "
1004 "skipping this line: %s",
1005 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1006 cstring_fromChars (line
)));
1007 fileloc_free (imploc
);
1011 op
= lslOp_renameSorts (map
, op
);
1013 llassert (op
!= NULL
);
1014 llassert (op
->name
!= NULL
);
1016 symtable_enterOp (g_symtab
, op
->name
,
1017 sigNode_copy (op
->signature
));
1018 /*@-mustfree@*/ } /*@=mustfree@*/
1019 else if (firstWord (line
, "type"))
1023 if (sscanf (line
, "type %s %s %s", namestr
, sostr
, kstr
) != 3)
1026 (message ("%q: illegal type declaration:\n skipping this line: %s",
1027 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1028 cstring_fromChars (line
)));
1029 fileloc_free (imploc
);
1033 ti
= (typeInfo
) dmalloc (sizeof (*ti
));
1034 ti
->id
= ltoken_createFull (LLT_TYPEDEF_NAME
, lsymbol_fromChars (namestr
),
1035 importfile
, inputStream_thisLineNumber (srce
), col
);
1037 bsort
= sort_lookupName (lsymbol_translateSort (map
, lsymbol_fromChars (sostr
)));
1039 if (sort_isNoSort (bsort
))
1041 lineptr
= strchr (line
, ' '); /* go past "type" */
1042 llassert (lineptr
!= NULL
);
1043 lineptr
= strchr (lineptr
+ 1, ' '); /* go past namestr */
1044 llassert (lineptr
!= NULL
);
1045 col
= 5 + ((int) (lineptr
- line
)); /* 5 for initial "%LCL "*/
1047 lclbug (message ("%q: Imported files contains unknown base sort",
1048 fileloc_unparseRawCol (importfile
, inputStream_thisLineNumber (srce
), col
)));
1052 ti
->basedOn
= bsort
;
1054 if (strcmp (kstr
, "exposed") == 0)
1056 ti
->abstract
= FALSE
;
1057 ti
->modifiable
= TRUE
;
1061 ti
->abstract
= TRUE
;
1062 if (strcmp (kstr
, "mutable") == 0)
1063 ti
->modifiable
= TRUE
;
1065 ti
->modifiable
= FALSE
;
1070 ** sort of a hack to get imports to work...
1075 cstring cnamestr
= cstring_fromChars (namestr
);
1077 if (!usymtab_existsGlobEither (cnamestr
))
1079 (void) usymtab_addEntry
1080 (uentry_makeDatatype
1081 (cnamestr
, ctype_unknown
,
1082 ti
->abstract
? ynm_fromBool (ti
->modifiable
) : MAYBE
,
1083 ti
->abstract
? qual_createAbstract () : qual_createConcrete (),
1084 fileloc_copy (imploc
)));
1088 symtable_enterType (g_symtab
, ti
);
1090 else if (firstWord (line
, "var"))
1094 if (sscanf (line
, "var %s %s", namestr
, sostr
) != 2)
1097 (message ("%q: Imported file contains illegal variable declaration. "
1098 "Skipping this line.",
1099 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
))));
1100 fileloc_free (imploc
);
1104 vi
= (varInfo
) dmalloc (sizeof (*vi
));
1105 bsort
= sort_lookupName (lsymbol_translateSort (map
, lsymbol_fromChars (sostr
)));
1106 lineptr
= strchr (line
, ' '); /* go past "var" */
1107 llassert (lineptr
!= NULL
);
1108 lineptr
= strchr (lineptr
+ 1, ' '); /* go past namestr */
1109 llassert (lineptr
!= NULL
);
1110 col
= 5 + ((int) (lineptr
- line
)); /* 5 for initial "%LCL "*/
1112 if (sort_isNoSort (bsort
))
1114 lclplainerror (message ("%q: Imported file contains unknown base sort",
1115 fileloc_unparseRawCol (importfile
, inputStream_thisLineNumber (srce
), col
)));
1119 vi
->id
= ltoken_createFull (simpleId
, lsymbol_fromChars (namestr
),
1120 importfile
, inputStream_thisLineNumber (srce
), col
);
1124 (void) symtable_enterVar (g_symtab
, vi
);
1129 cstring cnamestr
= cstring_fromChars (namestr
);
1131 if (!usymtab_existsGlobEither (cnamestr
))
1134 (void) usymtab_supEntrySref
1135 (uentry_makeVariable (cnamestr
, ctype_unknown
,
1136 fileloc_copy (imploc
),
1141 else if (firstWord (line
, "const"))
1145 if (sscanf (line
, "const %s %s", namestr
, sostr
) != 2)
1147 lclbug (message ("%q: Imported file contains illegal constant declaration: %s",
1148 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1149 cstring_fromChars (line
)));
1150 fileloc_free (imploc
);
1154 vi
= (varInfo
) dmalloc (sizeof (*vi
));
1155 bsort
= sort_lookupName (lsymbol_translateSort (map
, lsymbol_fromChars (sostr
)));
1156 lineptr
= strchr (line
, ' '); /* go past "var" */
1157 llassert (lineptr
!= NULL
);
1158 lineptr
= strchr (lineptr
+ 1, ' '); /* go past namestr */
1159 llassert (lineptr
!= NULL
);
1161 col
= 5 + ((int) (lineptr
- line
)); /* 5 for initial "%LCL "*/
1163 if (sort_isNoSort (bsort
))
1165 lclplainerror (message ("%q: Imported file contains unknown base sort",
1166 fileloc_unparseRawCol (importfile
, inputStream_thisLineNumber (srce
), col
)));
1170 vi
->id
= ltoken_createFull (simpleId
, lsymbol_fromChars (namestr
),
1171 importfile
, inputStream_thisLineNumber (srce
), col
);
1173 vi
->kind
= VRK_CONST
;
1175 (void) symtable_enterVar (g_symtab
, vi
);
1180 cstring cnamestr
= cstring_fromChars (namestr
);
1182 if (!usymtab_existsGlobEither (cnamestr
))
1185 (void) usymtab_addEntry (uentry_makeConstant (cnamestr
,
1187 fileloc_copy (imploc
)));
1190 /* must check for "fcnGlobals" before "fcn" */
1192 else if (firstWord (line
, "fcnGlobals"))
1194 pairNodeList globals
;
1195 lineptr
= strchr (line
, 'f'); /* remove any leading blanks */
1196 llassert (lineptr
!= NULL
);
1197 lineptr
= strchr (lineptr
, ' '); /* go past "fcnGlobals" */
1198 llassert (lineptr
!= NULL
);
1200 /* a quick check for empty fcnGlobals */
1201 if (!isBlankLine (lineptr
))
1203 globals
= parseGlobals (lineptr
, srce
);
1204 /* should ensure that each global in an imported function
1205 corresponds to some existing global. Since only
1206 "correctly processed" .lcs files are imported, this is
1207 true as an invariant. */
1211 globals
= pairNodeList_new ();
1214 /* check that they exist, store them on fctInfo */
1216 if (savedFcn
!= NULL
)
1218 pairNodeList_free ((*savedFcn
)->globals
);
1219 (*savedFcn
)->globals
= globals
; /* evs, moved inside if predicate */
1221 (void) symtable_enterFct (g_symtab
, *savedFcn
);
1227 (message ("%q: Unexpected function globals. "
1228 "Skipping this line: \n%s",
1229 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1230 cstring_fromChars (line
)));
1232 pairNodeList_free (globals
);
1235 else if (firstWord (line
, "fcn"))
1240 if (savedFcn
!= (fctInfo
*) 0)
1243 (message ("%q: illegal function declaration. Skipping this line:\n%s",
1244 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1245 cstring_fromChars (line
)));
1246 fileloc_free (imploc
);
1250 savedFcn
= (fctInfo
*) dmalloc (sizeof (*savedFcn
));
1252 lineptr
= strchr (line
, 'f'); /* remove any leading blanks */
1253 llassert (lineptr
!= NULL
);
1254 lineptr
= strchr (lineptr
, ' '); /* go past "fcn" */
1255 llassert (lineptr
!= NULL
);
1257 /* add a newline to the end of the line since parseOpLine expects it */
1259 lineptr2
= strchr (lineptr
, '\0');
1264 *(lineptr2
+ 1) = '\0';
1267 op
= parseOpLine (importfile
, cstring_fromChars (lineptr
+ 1));
1269 if (op
== (lslOp
) 0)
1272 (message ("%q: illegal function declaration: %s",
1273 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1274 cstring_fromChars (line
)));
1275 fileloc_free (imploc
);
1279 op2
= lslOp_renameSorts (map
, op
);
1281 llassert (op2
!= NULL
);
1283 if ((op
->name
!= NULL
) && op
->name
->isOpId
)
1285 (*savedFcn
) = (fctInfo
) dmalloc (sizeof (**savedFcn
));
1286 (*savedFcn
)->id
= op
->name
->content
.opid
;
1287 (*savedFcn
)->signature
= signNode_fromsigNode (op2
->signature
);
1288 (*savedFcn
)->globals
= pairNodeList_new ();
1289 (*savedFcn
)->export
= TRUE
;
1293 /* 27 Jan 1995 --- added this to be undefined namestr bug */
1294 cstring fname
= ltoken_unparse ((*savedFcn
)->id
);
1296 if (!usymtab_existsGlobEither (fname
))
1298 (void) usymtab_addEntry (uentry_makeFunction
1299 (fname
, ctype_unknown
,
1300 typeId_invalid
, globSet_new (),
1302 warnClause_undefined
,
1303 fileloc_copy (imploc
)));
1309 /* evans 2001-05-27: detected by splint after fixing external alias bug. */
1310 if (op
->name
!= NULL
)
1312 ltoken_free (op
->name
->content
.opid
);
1316 (message ("%q: unexpected function name: %s",
1317 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1318 cstring_fromChars (line
)));
1321 else if (firstWord (line
, "enumConst"))
1325 if (sscanf (line
, "enumConst %s %s", namestr
, sostr
) != 2)
1328 (message ("%q: Illegal enum constant declaration. "
1329 "Skipping this line:\n%s",
1330 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1331 cstring_fromChars (line
)));
1332 fileloc_free (imploc
);
1336 vi
= (varInfo
) dmalloc (sizeof (*vi
));
1337 bsort
= sort_lookupName (lsymbol_translateSort (map
, lsymbol_fromChars (sostr
)));
1338 lineptr
= strchr (line
, ' '); /* go past "var" */
1339 llassert (lineptr
!= NULL
);
1340 lineptr
= strchr (lineptr
+ 1, ' '); /* go past namestr */
1341 llassert (lineptr
!= NULL
);
1343 col
= 5 + ((int) (lineptr
- line
)); /* 5 for initial "%LCL "*/
1344 if (sort_isNoSort (bsort
))
1346 lclplainerror (message ("%q: unknown base sort\n",
1347 fileloc_unparseRawCol (importfile
, inputStream_thisLineNumber (srce
), col
)));
1351 vi
->id
= ltoken_createFull (simpleId
, lsymbol_fromChars (namestr
),
1352 importfile
, inputStream_thisLineNumber (srce
), col
);
1355 vi
->kind
= VRK_ENUM
;
1357 (void) symtable_enterVar (g_symtab
, vi
);
1362 cstring cnamestr
= cstring_fromChars (namestr
);
1363 if (!usymtab_existsEither (cnamestr
))
1365 (void) usymtab_addEntry (uentry_makeConstant (cnamestr
, ctype_unknown
,
1366 fileloc_copy (imploc
)));
1370 else if (firstWord (line
, "tag"))
1372 /* do nothing, sort processing already handles this */
1377 (message ("%q: Unknown symbol declaration. Skipping this line:\n%s",
1378 fileloc_unparseRaw (importfile
, inputStream_thisLineNumber (srce
)),
1379 cstring_fromChars (line
)));
1382 fileloc_free (imploc
);
1386 symtable_import (inputStream imported
, ltoken tok
, mapping map
)
1390 bool old_inImport
= inImport
;
1392 buf
= inputStream_nextLine (imported
);
1393 importfile
= inputStream_fileName (imported
);
1395 llassert (buf
!= NULL
);
1397 if (!firstWord (buf
, "%LCLSymbolTable"))
1400 message ("Expecting '%%LCLSymbolTable' line in import file %s:\n%s\n",
1402 cstring_fromChars (buf
)));
1405 allowed_redeclaration
= TRUE
;
1410 buf
= inputStream_nextLine (imported
);
1411 llassert (buf
!= NULL
);
1414 if (firstWord (buf
, "%LCLSymbolTableEnd"))
1419 { /* a good line, remove %LCL from line first */
1420 if (firstWord (buf
, "%LCL"))
1422 parseLine (buf
+ 4, imported
, map
);
1428 message ("Expecting '%%LCL' prefix in import file %s:\n%s\n",
1430 cstring_fromChars (buf
)));
1435 /* restore old value */
1436 inImport
= old_inImport
;
1437 allowed_redeclaration
= FALSE
;
1441 symtable_dumpId (symtable stable
, FILE *f
, bool lco
)
1443 idTable
*st
= stable
->idTable
;
1450 for (i
= 1; i
< st
->size
; i
++)
1452 /* 2/22/93 I think there is a off-by-1 error, 0 entry is never used */
1453 se
= st
->entries
+ i
;
1454 llassert (se
!= NULL
);
1457 /*@-loopswitchbreak@*/
1464 fi
= (se
->info
).fct
;
1468 fprintf (f
, "%%LCL");
1471 if (!lco
&& !fi
->export
)
1473 fprintf (f
, "spec ");
1476 tmp
= signNode_unparse (fi
->signature
);
1477 fprintf (f
, "fcn %s %s \n", ltoken_getTextChars (fi
->id
),
1478 cstring_toCharsSafe (tmp
));
1481 tmp
= pairNodeList_unparse (fi
->globals
);
1482 fprintf (f
, "%%LCLfcnGlobals %s\n", cstring_toCharsSafe (tmp
));
1492 /*@-switchswitchbreak@*/
1493 switch ((se
->info
).scope
->kind
)
1496 fprintf (f
, "Global scope\n");
1499 fprintf (f
, "Abstract type scope\n");
1502 fprintf (f
, "Function scope\n");
1504 /* a let scope can only occur in a function scope, should not push
1505 a new scope, so symtable_lookupInScope works properly
1507 fprintf (f, "Let scope\n");
1510 fprintf (f
, "Quantifier scope\n");
1513 fprintf (f
, "Claim scope\n");
1520 ti
= (se
->info
).type
;
1522 fprintf (f
, "%%LCL");
1523 if (!lco
&& !ti
->export
)
1524 fprintf (f
, "spec ");
1525 fprintf (f
, "type %s %s",
1526 ltoken_getTextChars (ti
->id
), sort_getName (ti
->basedOn
));
1530 fprintf (f
, " mutable\n");
1532 fprintf (f
, " immutable\n");
1535 fprintf (f
, " exposed\n");
1539 vi
= (se
->info
).var
;
1542 fprintf (f
, "%%LCL");
1545 if (!lco
&& !vi
->export
)
1547 fprintf (f
, "spec ");
1552 fprintf (f
, "const %s %s\n",
1553 ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1556 fprintf (f
, "var %s %s\n",
1557 ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1560 fprintf (f
, "enumConst %s %s\n",
1561 ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1569 fprintf (f
, "global %s %s\n", ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1571 case VRK_PRIVATE
: /* for private vars within function */
1572 fprintf (f
, "local %s %s\n",
1573 ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1576 fprintf (f
, "let %s %s\n",
1577 ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1580 fprintf (f
, "param %s %s\n",
1581 ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1584 fprintf (f
, "quant %s %s\n",
1585 ltoken_getTextChars (vi
->id
), sort_getName (vi
->sort
));
1589 /*@=loopswitchbreak@*/
1590 /*@=switchswitchbreak@*/
1597 static /*@exposed@*/ /*@out@*/ idTableEntry
*
1598 nextFree (idTable
* st
)
1601 unsigned int n
= st
->size
;
1603 if (n
>= st
->allocated
)
1606 ** this loses with the garbage collector
1607 ** (and realloc is notoriously dangerous)
1609 ** st->entries = (idTableEntry *) LSLMoreMem (st->entries, (n + DELTA)
1610 ** * sizeof (idTableEntry));
1612 ** instead, we copy the symtable...
1615 idTableEntry
*oldentries
= st
->entries
;
1618 st
->entries
= dmalloc ((n
+DELTA
) * sizeof (*st
->entries
));
1620 for (i
= 0; i
< n
; i
++)
1622 st
->entries
[i
] = oldentries
[i
];
1627 st
->allocated
= n
+ DELTA
;
1630 ret
= &(st
->entries
[st
->size
]);
1636 static /*@dependent@*/ /*@null@*/ idTableEntry
*
1637 symtable_lookup (idTable
*st
, lsymbol id
)
1642 for (n
= st
->size
- 1; n
>= 0; n
--)
1644 e
= &(st
->entries
[n
]);
1646 /*@-loopswitchbreak@*/
1652 if (ltoken_getText (e
->info
.fct
->id
) == id
) return e
;
1655 if (ltoken_getText (e
->info
.type
->id
) == id
) return e
;
1658 if (ltoken_getText (e
->info
.var
->id
) == id
) return e
;
1662 /*@=loopswitchbreak@*/
1665 return (idTableEntry
*) 0;
1669 static /*@dependent@*/ /*@null@*/ idTableEntry
*
1670 symtable_lookupInScope (idTable
*st
, lsymbol id
)
1674 for (n
= st
->size
- 1; n
>= 0; n
--)
1676 e
= &(st
->entries
[n
]);
1677 if (e
->kind
== SYMK_SCOPE
)
1679 if (ltoken_getText (e
->info
.fct
->id
) == id
)
1684 return (idTableEntry
*) 0;
1687 /* hash table implementation */
1690 htData_key (htData
* x
)
1692 /* assume x points to a valid htData struct */
1696 return x
->content
.sort
;
1698 { /* get the textSym of the token */
1699 nameNode n
= (x
->content
.op
)->name
;
1703 return ltoken_getText (n
->content
.opid
);
1707 llassert (n
->content
.opform
!= NULL
);
1708 return (n
->content
.opform
)->key
;
1712 return ltoken_getText ((x
->content
).tag
->id
);
1717 static void htData_free (/*@null@*/ /*@only@*/ htData
*d
)
1726 /* nameNode_free (d->content.op->name);*/
1727 sigNodeSet_free (d
->content
.op
->signatures
);
1731 switch (d
->content
.tag
->kind
)
1738 ** no: stDeclNodeList_free (d->content.tag->content.decls);
1741 /*@switchbreak@*/ break;
1744 /* no: ltokenList_free (d->content.tag->content.enums);
1748 /*@switchbreak@*/ break;
1757 static void bucket_free (/*@null@*/ /*@only@*/ bucket
*b
)
1761 bucket_free (b
->next
);
1762 htData_free (b
->data
);
1767 static void symHashTable_free (/*@only@*/ symHashTable
*h
)
1771 for (i
= 0; i
< h
->size
; i
++)
1773 bucket_free (h
->buckets
[i
]);
1780 static /*@only@*/ symHashTable
*
1781 symHashTable_create (unsigned int size
)
1784 symHashTable
*t
= (symHashTable
*) dmalloc (sizeof (*t
));
1786 t
->buckets
= (bucket
**) dmalloc ((size
+ 1) * sizeof (*t
->buckets
));
1790 for (i
= 0; i
<= size
; i
++)
1792 t
->buckets
[i
] = (bucket
*) NULL
;
1798 static /*@null@*/ /*@exposed@*/ htData
*
1799 symHashTable_get (symHashTable
*t
, symbolKey key
, infoKind kind
, /*@null@*/ nameNode n
)
1805 b
= t
->buckets
[MASH (key
, kind
)];
1806 if (b
== (bucket
*) 0)
1808 return ((htData
*) 0);
1811 for (entry
= (htEntry
*) b
; entry
!= NULL
; entry
= entry
->next
)
1815 if (d
->kind
== kind
&& htData_key (d
) == key
)
1816 if (kind
!= IK_OP
|| sameNameNode (n
, d
->content
.op
->name
))
1821 return ((htData
*) 0);
1825 symHashTable_put (symHashTable
*t
, /*@only@*/ htData
*data
)
1827 /* if key is already taken, don't insert, return FALSE
1828 else insert it and return TRUE. */
1834 key
= htData_key (data
);
1837 if (kind
== IK_OP
&& (!data
->content
.op
->name
->isOpId
))
1839 name
= data
->content
.op
->name
;
1843 name
= (nameNode
) 0;
1846 oldd
= symHashTable_get (t
, key
, kind
, name
);
1848 if (oldd
== (htData
*) 0)
1851 bucket
*new_entry
= (bucket
*) dmalloc (sizeof (*new_entry
));
1852 bucket
*b
= (t
->buckets
[MASH (key
, kind
)]);
1853 htEntry
*entry
= (htEntry
*) b
;
1856 new_entry
->data
= data
;
1857 new_entry
->next
= entry
;
1858 t
->buckets
[MASH (key
, kind
)] = new_entry
;
1871 static /*@only@*/ /*@exposed@*/ /*@null@*/ htData
*
1872 symHashTable_forcePut (symHashTable
*t
, /*@only@*/ htData
*data
)
1874 /* Put data in, return old value */
1878 htEntry
*entry
, *new_entry
;
1882 key
= htData_key (data
);
1885 if (kind
== IK_OP
&& (!data
->content
.op
->name
->isOpId
))
1887 name
= data
->content
.op
->name
;
1891 name
= (nameNode
) 0;
1894 oldd
= symHashTable_get (t
, key
, kind
, name
);
1896 if (oldd
== (htData
*) 0)
1898 new_entry
= (htEntry
*) dmalloc (sizeof (*new_entry
));
1901 b
= t
->buckets
[MASH (key
, kind
)];
1905 new_entry
->data
= data
;
1906 new_entry
->next
= entry
;
1907 t
->buckets
[MASH (key
, kind
)] = new_entry
;
1913 { /* modify in place */
1914 *oldd
= *data
; /* copy new info over to old info */
1916 /* dangerous: if the data is the same, don't free it */
1930 symHashTable_count (symHashTable
* t
)
1937 symHashTable_printStats (symHashTable
* t
)
1939 int i
, bucketCount
, setsize
, sortCount
, opCount
, tagCount
;
1940 int sortTotal
, opTotal
, tagTotal
;
1952 /* for debugging only */
1953 printf ("\n Printing symHashTable stats ... \n");
1954 for (i
= 0; i
<= HT_MAXINDEX
; i
++)
1958 for (entry
= b
; entry
!= NULL
; entry
= entry
->next
)
1966 /*@switchbreak@*/ break;
1969 cstring name
= nameNode_unparse (d
->content
.op
->name
);
1970 cstring sigs
= sigNodeSet_unparse (d
->content
.op
->signatures
);
1973 setsize
= sigNodeSet_size (d
->content
.op
->signatures
);
1974 printf (" Op (%d): %s %s\n", setsize
,
1975 cstring_toCharsSafe (name
),
1976 cstring_toCharsSafe (sigs
));
1977 cstring_free (name
);
1978 cstring_free (sigs
);
1979 /*@switchbreak@*/ break;
1983 /*@switchbreak@*/ break;
1986 if (bucketCount
> 0)
1988 printf (" Bucket %d has count = %d; opCount = %d; sortCount = %d; tagCount = %d\n", i
, bucketCount
, opCount
, sortCount
, tagCount
);
1989 sortTotal
+= sortCount
;
1990 tagTotal
+= tagCount
;
1994 printf ("SymHashTable has total count = %d, opTotal = %d, sortTotal = %d, tagTotal = %d :\n", t
->count
, opTotal
, sortTotal
, tagTotal
);
1999 symtable_printStats (symtable s
)
2001 symHashTable_printStats (s
->hTable
);
2002 /* for debugging only */
2003 printf ("idTable size = %d; allocated = %d\n",
2004 s
->idTable
->size
, s
->idTable
->allocated
);
2009 tagKind_unparse (tagKind k
)
2015 return cstring_makeLiteral ("struct");
2018 return cstring_makeLiteral ("union");
2020 return cstring_makeLiteral ("enum");
2025 static void tagInfo_free (/*@only@*/ tagInfo tag
)
2027 ltoken_free (tag
->id
);
2031 /*@observer@*/ sigNodeSet
2032 symtable_possibleOps (symtable tab
, nameNode n
)
2034 opInfo oi
= symtable_opInfo (tab
, n
);
2036 if (opInfo_exists (oi
))
2038 return (oi
->signatures
);
2041 return sigNodeSet_undefined
;
2045 symtable_opExistsWithArity (symtable tab
, nameNode n
, int arity
)
2047 opInfo oi
= symtable_opInfo (tab
, n
);
2049 if (opInfo_exists (oi
))
2051 sigNodeSet sigs
= oi
->signatures
;
2052 sigNodeSet_elements (sigs
, sig
)
2054 if (ltokenList_size (sig
->domain
) == arity
)
2056 } end_sigNodeSet_elements
;
2062 domainMatches (ltokenList domain
, sortSetList argSorts
)
2064 /* expect their length to match */
2065 /* each domain sort in op must be an element of
2066 the corresponding set in argSorts. */
2067 bool matched
= TRUE
;
2070 sortSetList_reset (argSorts
);
2071 ltokenList_elements (domain
, dom
)
2073 s
= sort_fromLsymbol (ltoken_getText (dom
));
2074 if (!(sortSet_member (sortSetList_current (argSorts
), s
)))
2076 /* printf (" mismatched element is: %s in %s\n", ltoken_getTextChars (*dom),
2077 sortSet_unparse (sortSetList_current (argSorts))); */
2081 sortSetList_advance (argSorts
);
2082 } end_ltokenList_elements
;
2088 symtable_opsWithLegalDomain (symtable tab
, /*@temp@*/ /*@null@*/ nameNode n
,
2089 sortSetList argSorts
, sort q
)
2091 /* handles nil qual */
2092 lslOpSet ops
= lslOpSet_new ();
2097 llassert (n
!= NULL
);
2098 oi
= symtable_opInfo (tab
, n
);
2100 if (opInfo_exists (oi
))
2102 sigNodeSet sigs
= oi
->signatures
;
2104 sigNodeSet_elements (sigs
, sig
)
2106 if (ltokenList_size (sig
->domain
) == sortSetList_size (argSorts
))
2108 rangeSort
= sigNode_rangeSort (sig
);
2110 if ((sort_isNoSort (q
)) || (sort_equal (rangeSort
, q
)))
2112 if (domainMatches (sig
->domain
, argSorts
))
2114 op
= (lslOp
) dmalloc (sizeof (*op
));
2116 /* each domain sort in op must be an element of
2117 the corresponding set in argSorts. */
2118 op
->signature
= sig
;
2119 op
->name
= nameNode_copy (n
);
2120 (void) lslOpSet_insert (ops
, op
);
2124 } end_sigNodeSet_elements
;