Bug Summary

File:src/stab.c
Warning:line 1493, column 17
Access to field 'id' results in a dereference of a null pointer (loaded from variable 'syme')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name stab.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/src -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/src -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -D VCSVERSION="2c53e759f1e00e345f8b172e7139debda72fda13" -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c stab.c
1/*****************************************************************************
2 *
3 * stab.c: Symbol table definitions.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9#include "ablogic.h"
10#include "abpretty.h"
11#include "axlobs.h"
12#include "comsg.h"
13#include "debug.h"
14#include "doc.h"
15#include "fint.h"
16#include "format.h"
17#include "lib.h"
18#include "sefo.h"
19#include "simpl.h"
20#include "spesym.h"
21#include "stab.h"
22#include "store.h"
23#include "strops.h"
24#include "table.h"
25#include "tfsat.h"
26#include "tposs.h"
27#include "tqual.h"
28
29Bool stabDebug = false((int) 0);
30Bool stabImportDebug = false((int) 0);
31Bool stabConstDebug = false((int) 0);
32
33#define stabDEBUGif (!stabDebug) { } else afprintf DEBUG_IF(stab)if (!stabDebug) { } else afprintf
34#define stabImportDEBUGif (!stabImportDebug) { } else afprintf DEBUG_IF(stabImport)if (!stabImportDebug) { } else afprintf
35#define stabConstDEBUGif (!stabConstDebug) { } else afprintf DEBUG_IF(stabConst)if (!stabConstDebug) { } else afprintf
36
37/****************************************************************************
38 *
39 * :: Local function declarations.
40 *
41 ****************************************************************************/
42
43localstatic StabEntry stabEntryNew (void);
44localstatic StabEntry stabEntryCopy (StabEntry);
45
46localstatic void stabEntryClearCache (StabEntry);
47localstatic void stabEntryAddCache (StabEntry, AbLogic, SymeList);
48
49localstatic void stabEntryPutSyme (StabEntry, Length, Syme);
50localstatic void stabEntryAddSyme (StabEntry, Syme);
51
52localstatic Bool stabEntryIsGeneric (StabEntry);
53
54localstatic SymeList stabEntryAllSymes (StabEntry);
55localstatic SymeList stabEntryGetSymes (StabEntry, AbLogic);
56localstatic SymeList stabEntryCacheSymes (StabEntry, AbLogic);
57
58localstatic TPoss stabEntryAllTypes (StabEntry);
59localstatic TPoss stabEntryGetTypes (StabEntry, AbLogic);
60localstatic TPoss stabEntryCacheTypes (StabEntry, Length);
61
62CREATE_LIST(TFormUses)struct TFormUses_listOpsStruct const *TFormUses_listPointer =
(struct TFormUses_listOpsStruct const *) &ptrlistOps
;
63
64typedef TFormUses(*UpdateTfuFun)(TFormUses);
65
66localstatic StabLevel stabNewLevel (int, int, SrcPos, Bool, Bool);
67localstatic StabEntry stabGetEntry (Stab, Symbol, Bool);
68localstatic int stabPrEntry (FILE *, TblKey);
69
70localstatic Bool stabImportIsCovered (SymeList, Syme, Stab);
71localstatic Bool stabExtendIsCovered (SymeList, Syme);
72
73localstatic void stabPropagateDecl (Stab, Syme);
74
75localstatic Bool symeHasExtendee (Syme, Syme);
76localstatic Syme symeListHasImportee (SymeList, Syme);
77localstatic void symeRefreshExtendees (Syme);
78
79localstatic Syme stabGetSymeOfKind (Stab, Symbol, SymeTag);
80localstatic Syme stabLevelGetSymeOfKind (Stab, Symbol, SymeTag);
81
82localstatic void stabImportRemark (Stab, TFormList, TForm);
83
84localstatic TFormUses tfuNew (TForm);
85localstatic TFormUses tfuSetFlag (Stab, TForm, UpdateTfuFun);
86localstatic TFormUses tformDoNothing (TFormUses);
87localstatic TFormUses tformIsImported (TFormUses);
88localstatic TFormUses tformExportAll (TFormUses);
89localstatic TFormUses tformImportAll (TFormUses);
90localstatic TFormUses tformInlineAll (TFormUses);
91localstatic TFormUses tformExplicitlyImportAll(TFormUses);
92localstatic TFormUses tformCategoricallyImport(TFormUses);
93localstatic TFormUses tformParameterImport (TFormUses);
94
95localstatic TForm addTFormUnused (Stab stab, TForm tf);
96localstatic TForm findTFormUnused (Stab stab, AbSyn ab);
97localstatic void removeTFormUnused (Stab stab, TForm tf);
98
99#define stabUseList(stab,ab)!(((stab)->first)->tformsUsed.table) !stabLevelIsLarge(stab)(((stab)->first)->tformsUsed.table)
100#define stabUseTable(stab,ab)(((stab)->first)->tformsUsed.table) stabLevelIsLarge(stab)(((stab)->first)->tformsUsed.table)
101
102#define tfuSetUnqualified(f,tf)((f) = (f) ? tqSetUnqualified(f) : tqNewUnqualified(tf)) \
103 ((f) = (f) ? tqSetUnqualified(f) : tqNewUnqualified(tf))
104#define tfuSetQualified(f,tf,q)((f) = (f) ? (((f)->isQual == 1) ? tqAddQual(f,q) : (f)) :
tqNewQualified(tf,q))
\
105 ((f) = (f) ? (tqIsQualified(f)((f)->isQual == 1) ? tqAddQual(f,q) : (f)) \
106 : tqNewQualified(tf,q))
107
108#define tfuCreateIfNeeded(f,tf)((f)=(f)?(f):tqNewEmpty(tf)) ((f)=(f)?(f):tqNewEmpty(tf))
109
110/****************************************************************************
111 *
112 * :: -Wdumb-import options
113 *
114 ****************************************************************************/
115
116static Bool stabDumbImportFlag = false((int) 0);
117
118Bool
119stabDumbImport(void)
120{
121 return stabDumbImportFlag;
122}
123
124
125void
126stabSetDumbImport(Bool flag)
127{
128 stabDumbImportFlag = flag;
129}
130
131/****************************************************************************
132 *
133 * :: stabMaxSerialNo/stabMaxDefnNum
134 *
135 ****************************************************************************/
136
137static ULong stabSerialNoCounter = 0; /* unique index per stab lvl */
138static ULong stabDefinitionCounter = 0; /* unique index per defn */
139
140ULong
141stabMaxSerialNo(void)
142{
143 return stabSerialNoCounter;
144}
145
146UShort
147stabMaxDefnNum(void)
148{
149 return stabDefinitionCounter;
150}
151
152/****************************************************************************
153 *
154 * :: StabGlobal/StabFile
155 *
156 ****************************************************************************/
157
158static Stab StabGlobal = 0; /* Persists across all files. */
159static Stab StabFile = 0; /* Persists across one file. */
160
161void
162stabInitGlobal(void)
163{
164 StabGlobal = stabNewGlobal();
165 return;
166}
167
168void
169stabInitFile(void)
170{
171 StabFile = stabNewFile(StabGlobal);
172 stabDefinitionCounter = 0;
173 return;
174}
175
176Stab
177stabNewGlobal(void)
178{
179 StabLevel slev = stabNewLevel(int0((int) 0), int0((int) 0), sposNone, false((int) 0), false((int) 0)); /* small */
180
181 Stab stab = listCons(StabLevel)(StabLevel_listPointer->Cons) (slev, listNil(StabLevel)((StabLevelList) 0));
182 stabClrSubstable(stab)(((stab)->first)->isSubstable=((int) 0));
183
184 return stab;
185}
186
187Stab
188stabNewFile(Stab globalStab)
189{
190 StabLevel slev = stabNewLevel(1, 1, sposNone, true1, false((int) 0)); /* large level */
191
192 Stab fileStab = listCons(StabLevel)(StabLevel_listPointer->Cons) (slev, globalStab);
193 assert(listLength(StabLevel)(globalStab) == 1)do { if (!((StabLevel_listPointer->_Length)(globalStab) ==
1)) _do_assert(("listLength(StabLevel)(globalStab) == 1"),"stab.c"
,193); } while (0)
;
194
195 stabClrSubstable(fileStab)(((fileStab)->first)->isSubstable=((int) 0));
196
197 return fileStab;
198}
199
200void
201stabFiniGlobal(void)
202{
203 /* stabFree(StabGlobal); */
204 StabGlobal = 0;
205 return;
206}
207
208void
209stabFiniFile(void)
210{
211 /* stabFree(StabFile); */
212 StabFile = 0;
213 return;
214}
215
216Stab
217stabGlobal(void)
218{
219 return StabGlobal;
220}
221
222Stab
223stabFile(void)
224{
225 return StabFile ? StabFile : StabGlobal;
226}
227
228/****************************************************************************
229 *
230 * :: Symbol table entries.
231 *
232 ****************************************************************************/
233
234/*
235 * Each stab entry has an array of syme lists, keyed by condition,
236 * which represents the cached result of stabGetSymes under various
237 * conditions.
238 *
239 * The cache is set up to make common accesses quickly:
240 * index 0 - condv == ablogTrue()
241 * The list of unconditional symes are always found here.
242 * index 1 - condv == ablogFalse()
243 * The list of all symes are found here, when conditional
244 * meanings exist for this symbol in this stab.
245 *
246 * So if no conditional symes are present, we go right to the list.
247 * If we ask for the symes present when no conditions are assumed, ditto.
248 * If we repeatedly ask for symes under the same condition, ditto.
249 * Otherwise we filter through the list of all symes (at index 1).
250 */
251
252#define StabEntryCacheSize4 4
253localstatic void stabEntryCheckConditions(StabEntry stent);
254
255localstatic StabEntry
256stabEntryNew(void)
257{
258 StabEntry stent;
259 Length argc, cc, i;
260
261 argc = StabEntryCacheSize4;
262 cc = sizeof(AbLogic *) + sizeof(SymeList *) + sizeof(TPoss *);
263 cc = sizeof(*stent) + argc * cc;
264
265 stent = (StabEntry) stoAlloc((unsigned) OB_Other0, cc);
266
267 stent->argc = 0;
268 stent->condv = (AbLogic *) (stent + 1);
269 stent->symev = (SymeList *) (stent->condv + argc);
270 stent->possv = (TPoss *) (stent->symev + argc);
271 stent->pending = listNil(Syme)((SymeList) 0);
272
273 for (i = 0; i < argc; i += 1) {
274 stent->condv[i] = NULL((void*)0);
275 stent->symev[i] = listNil(Syme)((SymeList) 0);
276 stent->possv[i] = NULL((void*)0);
277 }
278
279 stabEntryAddCache(stent, ablogTrue(), listNil(Syme)((SymeList) 0));
280
281 return stent;
282}
283
284localstatic StabEntry
285stabEntryCopy(StabEntry stent)
286{
287 StabEntry nstent = stabEntryNew();
288 Length i;
289
290 nstent->argc = stent->argc;
291 if (nstent->argc > 2) nstent->argc = 2;
292
293 for (i = 0; i < nstent->argc; i += 1) {
294 nstent->condv[i] = ablogCopy(stent->condv[i]);
295 nstent->symev[i] = listCopy(Syme)(Syme_listPointer->Copy)(stent->symev[i]);
296 nstent->possv[i] = tpossCopy(stent->possv[i]);
297 }
298 nstent->pending = listCopy(Syme)(Syme_listPointer->Copy)(stent->pending);
299
300 return nstent;
301}
302
303localstatic void
304stabEntryClearCache(StabEntry stent)
305{
306 Length i;
307
308 tpossFree(stent->possv[0]);
309 stent->possv[0] = NULL((void*)0);
310
311 if (stabEntryIsGeneric(stent))
312 return;
313
314 tpossFree(stent->possv[1]);
315 stent->possv[1] = NULL((void*)0);
316
317 for (i = 2; i < stent->argc; i += 1) {
318 ablogFree(stent->condv[i]);
319 listFree(Syme)(Syme_listPointer->Free)(stent->symev[i]);
320 tpossFree(stent->possv[i]);
321
322 stent->condv[i] = NULL((void*)0);
323 stent->symev[i] = listNil(Syme)((SymeList) 0);
324 stent->possv[i] = NULL((void*)0);
325 }
326 stent->argc = 2;
327}
328
329localstatic void
330stabEntryAddCache(StabEntry stent, AbLogic abl, SymeList symes)
331{
332 assert(stent->argc < StabEntryCacheSize)do { if (!(stent->argc < 4)) _do_assert(("stent->argc < StabEntryCacheSize"
),"stab.c",332); } while (0)
;
333 stent->condv[stent->argc] = abl;
334 stent->symev[stent->argc] = symes;
335 stent->possv[stent->argc] = NULL((void*)0);
336 stent->argc += 1;
337}
338
339localstatic void
340stabEntryPutSyme(StabEntry stent, Length i, Syme syme)
341{
342 stent->symev[i] = listCons(Syme)(Syme_listPointer->Cons)(syme, stent->symev[i]);
343}
344
345localstatic void
346stabEntryAddSyme(StabEntry stent, Syme syme)
347{
348 stabEntryClearCache(stent);
349
350 if (symeIsCheckCondIncomplete(syme)(((AInt) (SYFI_ExtraBits < (8 * sizeof(int)) && !(
((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_ExtraBits
))) ? (symeFieldInfo[SYFI_ExtraBits].def) : (((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_ExtraBits)))
? ((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme
)->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_ExtraBits))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_ExtraBits
)] : (symeFieldInfo[SYFI_ExtraBits].def)) : symeGetFieldFn(syme
,SYFI_ExtraBits))) & (0x0004))
) {
351 stent->pending = listCons(Syme)(Syme_listPointer->Cons)(syme, stent->pending);
352 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, "Pending condition: %pSyme %pAbSynList\n",
353 syme, symeCondition(syme));
354 }
355 if (!symeIsCondChecked(syme)(((AInt) (SYFI_ExtraBits < (8 * sizeof(int)) && !(
((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_ExtraBits
))) ? (symeFieldInfo[SYFI_ExtraBits].def) : (((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_ExtraBits)))
? ((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme
)->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_ExtraBits))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_ExtraBits
)] : (symeFieldInfo[SYFI_ExtraBits].def)) : symeGetFieldFn(syme
,SYFI_ExtraBits))) & (0x0008))
&& symeCondition(syme)) {
356 stent->pending = listCons(Syme)(Syme_listPointer->Cons)(syme, stent->pending);
357 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, "Pending condition [unchecked]: %pSyme %pAbSynList\n",
358 syme, symeCondition(syme));
359 }
360 if (symeCondIsLazy(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x8000))
) {
361 stabEntryPutSyme(stent, int0((int) 0), syme);
362 if (!stabEntryIsGeneric(stent))
363 stabEntryPutSyme(stent, 1, syme);
364 }
365 else if (symeCondition(syme)) {
366 if (stabEntryIsGeneric(stent)) {
367 SymeList osymes = stent->symev[0];
368 stabEntryAddCache(stent, ablogFalse(), osymes);
369 }
370 stabEntryPutSyme(stent, 1, syme);
371 }
372 else {
373 stabEntryPutSyme(stent, int0((int) 0), syme);
374 if (!stabEntryIsGeneric(stent))
375 stabEntryPutSyme(stent, 1, syme);
376 }
377}
378
379localstatic Bool
380stabEntryIsGeneric(StabEntry stent)
381{
382 /* Return true if all symes in stent are unconditional. */
383 return stent->argc == 1;
384}
385
386localstatic SymeList
387stabEntryAllSymes(StabEntry stent)
388{
389 return stabEntryGetSymes(stent, ablogFalse());
390}
391
392localstatic SymeList
393stabEntryGetSymes(StabEntry stent, AbLogic abl)
394{
395 Length i;
396 SymeList symes;
397
398 if (abl != NULL((void*)0) && ablogEqual(abl, ablogFalse())) {
399 if (stent->argc == 1) {
400 return stent->symev[0];
401 }
402 else {
403 assert(ablogEqual(stent->condv[1], ablogFalse()))do { if (!(ablogEqual(stent->condv[1], ablogFalse()))) _do_assert
(("ablogEqual(stent->condv[1], ablogFalse())"),"stab.c",403
); } while (0)
;
404 return stent->symev[1];
405 }
406 }
407
408 stabEntryCheckConditions(stent);
409
410 /* Generic entry: no conditional symes, return them all. */
411 if (stent->argc == 1)
412 return stent->symev[0];
413
414 /* Generic query: return the unconditional symes. */
415 if (abl == NULL((void*)0) || ablogIsTrue(abl))
416 return stent->symev[0];
417
418 /* Check the cache. */
419 for (i = 1; i < stent->argc; i += 1)
420 if (ablogEqual(abl, stent->condv[i]))
421 return stent->symev[i];
422
423 /* Filter the symes. */
424 symes = stabEntryCacheSymes(stent, abl);
425
426 /* Cache the result. */
427 if (stent->argc < StabEntryCacheSize4)
428 stabEntryAddCache(stent, ablogCopy(abl), listCopy(Syme)(Syme_listPointer->Copy)(symes));
429
430 return symes;
431}
432
433localstatic void
434stabEntryCheckConditions(StabEntry stent)
435{
436 SymeList psymes, npsymes;
437
438 psymes = stent->pending;
439 npsymes = listNil(Syme)((SymeList) 0);
440 while (psymes != listNil(Syme)((SymeList) 0)) {
441 Syme psyme = car(psymes)((psymes)->first);
442 psymes = cdr(psymes)((psymes)->rest);
443
444 if (!symeCheckCondition(psyme)) {
445 continue;
446 }
447
448 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, "Checked: %pSyme - complete: %d condition: %pAbSynList\n",
449 psyme, symeIsCheckCondIncomplete(psyme)(((AInt) (SYFI_ExtraBits < (8 * sizeof(int)) && !(
((((psyme)->kind == SYME_Trigger ? libGetAllSymes((psyme)->
lib) : ((void*)0)), (psyme))->hasmask) & (1 << (
SYFI_ExtraBits))) ? (symeFieldInfo[SYFI_ExtraBits].def) : (((
((psyme)->kind == SYME_Trigger ? libGetAllSymes((psyme)->
lib) : ((void*)0)), (psyme))->locmask) & (1 << (
SYFI_ExtraBits))) ? ((((((psyme)->kind == SYME_Trigger ? libGetAllSymes
((psyme)->lib) : ((void*)0)), (psyme))->locmask) & (
1 << (SYFI_ExtraBits))) ? ((psyme)->fieldv)[symeIndex
(psyme,SYFI_ExtraBits)] : (symeFieldInfo[SYFI_ExtraBits].def)
) : symeGetFieldFn(psyme,SYFI_ExtraBits))) & (0x0004))
,
450 symeCondition(psyme));
451
452 if (symeCondition(psyme) == listNil(Sefo)((SefoList) 0)) {
453 stabEntryPutSyme(stent, int0((int) 0), psyme);
454 }
455 if (symeIsCheckCondIncomplete(psyme)(((AInt) (SYFI_ExtraBits < (8 * sizeof(int)) && !(
((((psyme)->kind == SYME_Trigger ? libGetAllSymes((psyme)->
lib) : ((void*)0)), (psyme))->hasmask) & (1 << (
SYFI_ExtraBits))) ? (symeFieldInfo[SYFI_ExtraBits].def) : (((
((psyme)->kind == SYME_Trigger ? libGetAllSymes((psyme)->
lib) : ((void*)0)), (psyme))->locmask) & (1 << (
SYFI_ExtraBits))) ? ((((((psyme)->kind == SYME_Trigger ? libGetAllSymes
((psyme)->lib) : ((void*)0)), (psyme))->locmask) & (
1 << (SYFI_ExtraBits))) ? ((psyme)->fieldv)[symeIndex
(psyme,SYFI_ExtraBits)] : (symeFieldInfo[SYFI_ExtraBits].def)
) : symeGetFieldFn(psyme,SYFI_ExtraBits))) & (0x0004))
) {
456 npsymes = listCons(Syme)(Syme_listPointer->Cons)(psyme, npsymes);
457 }
458 }
459 listFree(Syme)(Syme_listPointer->Free)(stent->pending);
460 stent->pending = npsymes;
461}
462
463
464localstatic SymeList
465stabEntryCacheSymes(StabEntry stent, AbLogic abl)
466{
467 SymeList symes, nsymes;
468
469 /* When conditional symes are present, all symes are at index 1. */
470 nsymes = listNil(Syme)((SymeList) 0);
471 for (symes = stent->symev[1]; symes; symes = cdr(symes)((symes)->rest)) {
472 Syme syme = car(symes)((symes)->first);
473 if (ablogIsListImplied(abl, symeCondition(syme)))
474 nsymes = listCons(Syme)(Syme_listPointer->Cons)(syme, nsymes);
475 }
476
477 nsymes = listNReverse(Syme)(Syme_listPointer->NReverse)(nsymes);
478 return nsymes;
479}
480
481localstatic TPoss
482stabEntryAllTypes(StabEntry stent)
483{
484 return stabEntryGetTypes(stent, ablogFalse());
485}
486
487localstatic TPoss
488stabEntryGetTypes(StabEntry stent, AbLogic abl)
489{
490 Length i;
491 SymeList symes;
492 TPoss tposs;
493
494 stabEntryCheckConditions(stent);
495
496 /* Generic query: return the unconditional types. */
497 if (abl == NULL((void*)0) || ablogIsTrue(abl))
498 return stabEntryCacheTypes(stent, int0((int) 0));
499
500 /* Check the cache. */
501 for (i = 1; i < stent->argc; i += 1)
502 if (ablogEqual(abl, stent->condv[i]))
503 return stabEntryCacheTypes(stent, i);
504
505 /* Filter the symes. */
506 symes = stabEntryCacheSymes(stent, abl);
507 tposs = tpossFrSymes(symes);
508
509 /* Cache the result. */
510 if (stent->argc < StabEntryCacheSize4) {
511 stabEntryAddCache(stent, ablogCopy(abl), symes);
512 stent->possv[i] = tpossRefer(tposs);
513 }
514
515 return tposs;
516}
517
518localstatic TPoss
519stabEntryCacheTypes(StabEntry stent, Length i)
520{
521 assert(i < stent->argc)do { if (!(i < stent->argc)) _do_assert(("i < stent->argc"
),"stab.c",521); } while (0)
;
522 if (stent->possv[i] == NULL((void*)0))
523 stent->possv[i] = tpossFrSymes(stent->symev[i]);
524 return tpossRefer(stent->possv[i]);
525}
526
527/****************************************************************************
528 *
529 * Local structure manipulation.
530 *
531 ****************************************************************************/
532
533localstatic StabLevel
534stabNewLevel(int levno, int lamno, SrcPos spos, Bool isLargeLevel, Bool isGenerator)
535{
536 StabLevel slev;
537
538 slev = (StabLevel) stoAlloc((unsigned) OB_Stab(14 + 6), sizeof(*slev));
539
540 slev->lexicalLevel = levno;
541 slev->lambdaLevel = lamno;
542 slev->serialNo = stabSerialNoCounter++;
543 slev->hash = slev->serialNo;
544 slev->isLocked = false((int) 0);
545 slev->isChecked = false((int) 0);
546 slev->isSubstable = true1;
547 slev->isGenerator = isGenerator;
548 slev->intStepNo = intStepNo;
549 slev->tbl = tblNew((TblHashFun) 0, (TblEqFun) 0);
550 slev->children = listNil(Stab)((StabList) 0);
551 slev->spos = spos;
552 slev->idsInScope = 0;
553 slev->labelsInScope = listNil(AbSyn)((AbSynList) 0);
554
555 slev->tformsUsed.list = listNil(TFormUses)((TFormUsesList) 0);
556 slev->tformsUnused = listNil(TForm)((TFormList) 0);
557
558 /*
559 * large levels have a non-0 hash table for faster lookup of tforms.
560 */
561 slev->tformsUsed.table = isLargeLevel ?
562 tblNew((TblHashFun) abHash, (TblEqFun) abEqual) : NULL((void*)0);
563
564 slev->boundSymes = listNil(Syme)((SymeList) 0);
565 slev->extendSymes = listNil(Syme)((SymeList) 0);
566 slev->exportedTypes = NULL((void*)0);
567
568 return slev;
569}
570
571/****************************************************************************
572 *
573 * Exported operations.
574 *
575 ****************************************************************************/
576
577Stab
578stabPushLevel(Stab stab, SrcPos spos, ULong flags)
579{
580 StabLevel slev;
581 Stab oldStab = stab;
582 int levno, lamno;
583
584 Bool isLargeLevel = (flags & STAB_LEVEL_LARGE(1<<1)) ? 1 : 0;
585 Bool isLoopLevel = (flags & STAB_LEVEL_LOOP(1<<2)) ? 1 : 0;
586 Bool isCollectLevel= (flags & STAB_LEVEL_COLLECT(1<<5)) ? 1 : 0;
587 Bool isWhereLevel = (flags & STAB_LEVEL_WHERE(1<<3)) ? 1 : 0;
588 Bool isGenLevel = (flags & STAB_LEVEL_XGENERATE(1<<4)) ? 1 : 0;
589 Bool isLoopLike = isLoopLevel || isCollectLevel;
590 Bool isProgLevel = !isLoopLike && !isWhereLevel;
591
592 assert(stab != 0)do { if (!(stab != 0)) _do_assert(("stab != 0"),"stab.c",592)
; } while (0)
;
593
594 levno = car(stab)((stab)->first)->lexicalLevel + (isLoopLike ? 0 : 1);
595 lamno = car(stab)((stab)->first)->lambdaLevel + (isProgLevel ? 1 : 0);
596
597 slev = stabNewLevel(levno, lamno, spos, isLargeLevel, isGenLevel);
598 stab = listCons(StabLevel)(StabLevel_listPointer->Cons) (slev, stab);
599 car(oldStab)((oldStab)->first)->children =
600 listCons(Stab)(Stab_listPointer->Cons) (stab, car(oldStab)((oldStab)->first)->children);
601
602 return stab;
603}
604
605Stab
606stabPopLevel(Stab stab)
607{
608 return cdr(stab)((stab)->rest);
609}
610
611void
612stabFree(Stab stab)
613{
614 /*!!*/
615}
616
617/******************************************************************************
618 *
619 * :: Symbol lookup
620 *
621 *****************************************************************************/
622
623/*
624 * Get entry for "id" in "stab". If "id" has never been searched at this
625 * level, then the meanings from the outer level are added at this level.
626 */
627
628localstatic StabEntry
629stabGetEntry(Stab stab0, Symbol id, Bool recurse)
630{
631 Stab stab;
632 StabEntry stent;
633 Bool first = true1;
634
635 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, "Searching for symbol %s", symString(id)((id)->str));
636
637 stab = stab0;
638 stent = 0;
639 while (stab && !stent) {
640 stabDEBUGif (!stabDebug) { } else afprintf(dbOut,
641 (first ? " looking in level %lu" : ", %lu"),
642 stabLevelNo(stab)(((stab)->first)->lexicalLevel));
643 first = false((int) 0);
644 stent = (StabEntry) tblElt(car(stab)((stab)->first)->tbl, id, NULL((void*)0));
645 if (! recurse)
646 break;
647 if (! stent)
648 stab = cdr(stab)((stab)->rest);
649 }
650
651 if (!stent) {
652 stent = stabEntryNew();
653 tblSetElt(car(stab0)((stab0)->first)->tbl, id, stent);
654 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, " ... manufacturing");
655 }
656 else if (stab != stab0) {
657 stent = stabEntryCopy(stent);
658 tblSetElt(car(stab0)((stab0)->first)->tbl, id, stent);
659 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, " ... copying");
660 }
661
662
663 if (DEBUG(stab)stabDebug) {
664 fnewline(dbOut);
665 }
666 stabEntryGetTypes(stent, ablogFalse());
667
668 if (DEBUG(stab)stabDebug) {
669 SymeList sl = stabEntryAllSymes(stent);
670 TPoss tp = stabEntryAllTypes(stent);
671 int i;
672
673 if (sl) {
674 findent += 2;
675 fnewline(dbOut);
676 fprintf(dbOut, "Meanings found: ");
677 findent++;
678 fnewline(dbOut);
679 for (i = 1; sl; i++, sl = cdr(sl)((sl)->rest)) {
680 fprintf(dbOut,"%2d. ",i);
681 symePrint(dbOut, car(sl)((sl)->first));
682 if (cdr(sl)((sl)->rest))
683 fnewline(dbOut);
684 }
685 findent -= 3;
686 }
687
688 if (tp && tpossCount(tp)) {
689 TPossIterator tit;
690
691 findent += 2;
692 fnewline(dbOut);
693 fprintf(dbOut, "Types found:");
694 findent++;
695 fnewline(dbOut);
696
697 for (i = 1, tpossITER(tit, tp)((tit).possl = (tp ? (tp)->possl : ((void*)0)));
698 tpossMORE(tit)((tit).possl);
699 i++, tpossSTEP(tit)((tit).possl = (((tit).possl)->rest)))
700 {
701 fprintf(dbOut,"%2d. ",i);
702 tfPrint(dbOut, tpossELT(tit)tpossELT_(&tit));
703 if (tpossMORE(tit)((tit).possl))
704 fnewline(dbOut);
705 }
706 findent -= 3;
707 }
708 fnewline(dbOut);
709 }
710
711 return stent;
712}
713
714/*
715 * For each constant symbol here, add meanings from outer levels.
716 */
717
718void
719stabSeeOuterImports(Stab stab0)
720{
721 TableIterator it;
722
723 for (tblITER(it, car(stab0)->tbl)_tblITER(&(it), ((stab0)->first)->tbl); tblMORE(it)((it).curr <= (it).last); tblSTEP(it)((((it).link=(it).link->next))==0 ? _tblSTEP(&(it)) : 1
)
) {
724 Symbol symb = (Symbol) tblKEY(it)((it).link->key);
725 StabEntry stent0 = (StabEntry) tblELT(it)((it).link->elt);
726 SymeList symes0 = stabEntryAllSymes(stent0);
727 Stab stab;
728 StabEntry stent = NULL((void*)0);
729 SymeList symes;
730
731 /* Consider only symbols with constant meanings. */
732 if (symes0 == NULL((void*)0))
733 continue;
734
735 if (symeIsParam(car(symes0))(((((((symes0)->first))->kind == SYME_Trigger ? libGetAllSymes
((((symes0)->first))->lib) : ((void*)0)), (((symes0)->
first)))->kind) == SYME_Param)
||
736 symeIsLexVar(car(symes0))(((((((symes0)->first))->kind == SYME_Trigger ? libGetAllSymes
((((symes0)->first))->lib) : ((void*)0)), (((symes0)->
first)))->kind) == SYME_LexVar)
||
737 symeIsExtend(car(symes0))(((((((symes0)->first))->kind == SYME_Trigger ? libGetAllSymes
((((symes0)->first))->lib) : ((void*)0)), (((symes0)->
first)))->kind) == SYME_Extend)
)
738 continue;
739
740 /* Establish there is something to add. */
741 for (stab = cdr(stab0)((stab0)->rest); !stent && stab; stab = cdr(stab)((stab)->rest))
742 stent = (StabEntry) tblElt(car(stab)((stab)->first)->tbl, symb, NULL((void*)0));
743 if (stent == NULL((void*)0))
744 continue;
745
746 /* Get outer meanings that are not covered. */
747 /* Outer imports are covered by local exports. */
748 for (symes = stabEntryAllSymes(stent); symes; symes = cdr(symes)((symes)->rest)) {
749 Syme syme = car(symes)((symes)->first);
750 Bool covered;
751
752 if (listMemq(Syme)(Syme_listPointer->Memq)(symes0, syme))
753 covered = true1;
754 else if (symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
)
755 covered = stabExtendIsCovered(symes0, syme);
756 else if (symeIsImport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Import)
)
757 covered = stabImportIsCovered(symes0, syme,
758 stab0);
759 else
760 covered = false((int) 0);
761
762 if (!covered)
763 stabEntryAddSyme(stent0, syme);
764 }
765 }
766}
767
768localstatic Bool
769stabImportIsCovered(SymeList symes, Syme syme, Stab stab)
770{
771 Syme syme0;
772 TForm tf0;
773 SymeList aself;
774 Syme asyme;
775 TForm tfd;
776
777 if (symeListHasImportee(symes, syme))
778 return true1;
779
780 for (; symes; symes = cdr(symes)((symes)->rest)) {
781 syme0 = car(symes)((symes)->first);
782 if (!symeIsExport(syme0)(((((syme0)->kind == SYME_Trigger ? libGetAllSymes((syme0)
->lib) : ((void*)0)), (syme0))->kind) == SYME_Export)
) continue;
783
784 tf0 = symeType(syme0);
785 if (tfEqual(symeType(syme), tf0))
786 return true1;
787
788 if (!tfEqual(symeType(symeOriginal(syme)), tf0))
789 continue;
790
791 aself = tfGetSelfFrStab(stab);
792 asyme = (aself ? car(aself)((aself)->first) : NULL((void*)0));
793 tfd = (asyme ? symeType(asyme) : NULL((void*)0));
794 if (tfd && tfIsDefineOfType(tfd) &&
795 tfEqual(tfDefineVal(tfd)tfFollowArg(tfd, 1), symeExporter(syme)))
796 return true1;
797 }
798 return false((int) 0);
799}
800
801localstatic Bool
802stabExtendIsCovered(SymeList symes, Syme syme)
803{
804 for (; symes; symes = cdr(symes)((symes)->rest))
805 if (symeExtension(car(symes)((symes)->first)) == syme)
806 return true1;
807 return false((int) 0);
808}
809
810void
811stabGetSubstable(Stab stab)
812{
813 SymeList symes;
814
815 if (stab == stabGlobal()) return;
816
817 stabLevelIsSubstable(stab)(((stab)->first)->isSubstable) = stabLevelIsSubstable(cdr(stab))(((((stab)->rest))->first)->isSubstable);
818 symes = stabGetBoundSymes(stab)(((stab)->first)->boundSymes);
819 for (; !stabLevelIsSubstable(stab)(((stab)->first)->isSubstable) && symes; symes = cdr(symes)((symes)->rest))
820 if (symeIsSubstable(car(symes))((((((((symes)->first))->kind == SYME_Trigger ? libGetAllSymes
((((symes)->first))->lib) : ((void*)0)), (((symes)->
first)))->kind) == SYME_Param) || (((((((symes)->first)
)->kind == SYME_Trigger ? libGetAllSymes((((symes)->first
))->lib) : ((void*)0)), (((symes)->first)))->kind) ==
SYME_LexConst) || (((((symes)->first))->id) == ssymSelf
) || ((((((((symes)->first))->kind == SYME_Trigger ? libGetAllSymes
((((symes)->first))->lib) : ((void*)0)), (((symes)->
first)))->kind) == SYME_Export) && !symeTop(((symes
)->first))))
)
821 stabSetSubstable(stab)(((stab)->first)->isSubstable=1);
822}
823
824void
825stabExtendMeanings(Stab stab, Syme syme)
826{
827 StabEntry stent = stabGetEntry(stab, symeId(syme)((syme)->id), true1);
828 Length i;
829
830 if (stent) {
831 stabEntryClearCache(stent);
832 for (i = 0; i < stent->argc; i += 1) {
833 stent->symev[i] = symeListExtend(stent->symev[i], syme);
834
835 }
836 }
837
838 car(stab)((stab)->first)->boundSymes = symeListExtend(car(stab)((stab)->first)->boundSymes, syme);
839}
840
841SymeList
842symeListExtend(SymeList symes, Syme syme)
843{
844 SymeList result;
845 Syme xsyme;
846
847 if (symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
)
848 xsyme = syme;
849 else if (symeIsImportOfExtend(syme)((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Import) &&
(((((symeOriginal(syme))->kind == SYME_Trigger ? libGetAllSymes
((symeOriginal(syme))->lib) : ((void*)0)), (symeOriginal(syme
)))->kind) == SYME_Extend))
)
850 xsyme = symeOriginal(syme);
851 else
852 return symes;
853
854 result = listNil(Syme)((SymeList) 0);
855
856#if 0
857{
858 SymeList tmp = symes;
859
860 printf("(Adding: %p %p %s\nCurrent: %s\nOrigin: %s\n",
861 syme, xsyme,
862 syme->id->str,
863 syme->lib && syme->lib->name ? syme->lib->name->partv[1]: "Local",
864 xsyme->lib->name->partv[1]);
865
866
867 while (tmp) {
868 printf("%p %s %s\n", car(tmp)((tmp)->first),
869 car(tmp)((tmp)->first)->lib && car(tmp)((tmp)->first)->lib->name
870 ? car(tmp)((tmp)->first)->lib->name->partv[1] : "Local",
871 car(tmp)((tmp)->first)->id->str);
872 tmp = cdr(tmp)((tmp)->rest);
873 }
874 printf("\n");
875}
876#endif
877 for (; symes; symes = listFreeCons(Syme)(Syme_listPointer->FreeCons)(symes)) {
878 /*if (symeOriginal(car(symes)) == xsyme)
879 stabExtendPair(symeOriginal(car(symes)), xsyme);
880 else*/ if (car(symes)((symes)->first) != syme && symeExtension(car(symes)((symes)->first)) != syme)
881 result = listCons(Syme)(Syme_listPointer->Cons)(car(symes)((symes)->first), result);
882 else {
883#if 0
884 printf("Deleted: %p %s %s\n",
885 car(symes)((symes)->first),
886 car(symes)((symes)->first)->lib && car(symes)((symes)->first)->lib->name
887 ? car(symes)((symes)->first)->lib->name->partv[1] : "Local",
888 car(symes)((symes)->first)->id->str);
889#endif
890 }
891 }
892 result = listCons(Syme)(Syme_listPointer->Cons)(syme, listNReverse(Syme)(Syme_listPointer->NReverse)(result));
893
894 return result;
895}
896
897/* Is syme1 an extendee of syme2? */
898localstatic Bool
899symeHasExtendee(Syme syme1, Syme syme2)
900{
901 SymeList symes;
902 Bool result = false((int) 0);
903
904 assert(symeIsExtend(syme2))do { if (!((((((syme2)->kind == SYME_Trigger ? libGetAllSymes
((syme2)->lib) : ((void*)0)), (syme2))->kind) == SYME_Extend
))) _do_assert(("symeIsExtend(syme2)"),"stab.c",904); } while
(0)
;
905
906 symes = symeExtendee(syme2);
907 for (; !result && symes; symes = cdr(symes)((symes)->rest)) {
908 Syme ext0 = car(symes)((symes)->first);
909 Syme ext1 = symeExtension(ext0);
910 symeSetExtension(ext0, NULL)symeXSetExtension(ext0, (AInt) ((void*)0));
911 result = symeEqual(symeOriginal(syme1), ext0);
912 symeSetExtension(ext0, ext1)symeXSetExtension(ext0, (AInt) ext1);
913 }
914
915 return result;
916}
917
918/* Is there an import for syme2 in symes? */
919localstatic Syme
920symeListHasImportee(SymeList symes, Syme syme2)
921{
922 Syme result = NULL((void*)0);
923
924 for (; !result && symes; symes = cdr(symes)((symes)->rest)) {
925 Syme syme1 = car(symes)((symes)->first);
926 if (symeIsImport(syme1)(((((syme1)->kind == SYME_Trigger ? libGetAllSymes((syme1)
->lib) : ((void*)0)), (syme1))->kind) == SYME_Import)
&& symeIsImport(syme2)(((((syme2)->kind == SYME_Trigger ? libGetAllSymes((syme2)
->lib) : ((void*)0)), (syme2))->kind) == SYME_Import)
&&
927 symeOriginal(syme1) == symeOriginal(syme2) &&
928 tformEqual(symeExporter(syme1), symeExporter(syme2)) &&
929 tformEqual(symeType(syme1), symeType(syme2)) &&
930 sefoListEqualMod(NULL((void*)0), symeCondition(syme1),
931 symeCondition(syme2)))
932 result = syme1;
933 }
934 return result;
935}
936
937/* Is there an extension of syme1 in symes? */
938Syme
939symeListHasExtension(SymeList symes, Syme syme1)
940{
941 Syme result = NULL((void*)0);
942
943 for (; !result && symes; symes = cdr(symes)((symes)->rest)) {
944 Syme syme2 = car(symes)((symes)->first);
945 if (symeIsImportOfExtend(syme2)((((((syme2)->kind == SYME_Trigger ? libGetAllSymes((syme2
)->lib) : ((void*)0)), (syme2))->kind) == SYME_Import) &&
(((((symeOriginal(syme2))->kind == SYME_Trigger ? libGetAllSymes
((symeOriginal(syme2))->lib) : ((void*)0)), (symeOriginal(
syme2)))->kind) == SYME_Extend))
&&
946 symeHasExtendee(syme1, symeOriginal(syme2)))
947 result = syme2;
948 }
949 return result;
950}
951
952/* Is there an extendee of syme2 in symes? */
953Syme
954symeListHasExtendee(SymeList symes, Syme syme2)
955{
956 Syme result = NULL((void*)0);
957
958 for (; !result && symes; symes = cdr(symes)((symes)->rest)) {
959 Syme syme1 = car(symes)((symes)->first);
960 if (symeIsImportOfExtend(syme2)((((((syme2)->kind == SYME_Trigger ? libGetAllSymes((syme2
)->lib) : ((void*)0)), (syme2))->kind) == SYME_Import) &&
(((((symeOriginal(syme2))->kind == SYME_Trigger ? libGetAllSymes
((symeOriginal(syme2))->lib) : ((void*)0)), (symeOriginal(
syme2)))->kind) == SYME_Extend))
&&
961 symeHasExtendee(syme1, symeOriginal(syme2)))
962 result = syme1;
963 }
964
965 return result;
966}
967
968localstatic void
969symeRefreshExtendees(Syme syme)
970{
971 SymeList symes;
972
973 assert(symeIsImportOfExtend(syme))do { if (!(((((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->kind) == SYME_Import
) && (((((symeOriginal(syme))->kind == SYME_Trigger
? libGetAllSymes((symeOriginal(syme))->lib) : ((void*)0))
, (symeOriginal(syme)))->kind) == SYME_Extend)))) _do_assert
(("symeIsImportOfExtend(syme)"),"stab.c",973); } while (0)
;
974 syme = symeOriginal(syme);
975
976 symes = symeExtendee(syme);
977 for (; symes; symes = cdr(symes)((symes)->rest)) {
978 Syme ext = car(symes)((symes)->first);
979 if (symeExtension(ext) == NULL((void*)0))
980 symeSetExtension(ext, syme)symeXSetExtension(ext, (AInt) syme);
981 }
982}
983
984SymeList
985stabGetMeanings(Stab stab, AbLogic abl, Symbol sym)
986{
987 StabEntry stent = stabGetEntry(stab, sym, true1);
988 return stent ? stabEntryGetSymes(stent, abl) : listNil(Syme)((SymeList) 0);
989}
990
991TPoss
992stabGetTypes(Stab stab, AbLogic abl, Symbol sym)
993{
994 StabEntry stent = stabGetEntry(stab, sym, true1);
995 return stent ? stabEntryGetTypes(stent, abl) : tpossEmpty();
996}
997
998/*
999 * Get the symbol meaning for %, or return NULL for failure.
1000 */
1001Syme
1002stabGetSelf(Stab stab)
1003{
1004 StabEntry stent;
1005 SymeList symes;
1006
1007 if (stab == NULL((void*)0)) return NULL((void*)0);
1008
1009 stent = stabGetEntry(stab, ssymSelf, false((int) 0));
1010 if (stent == NULL((void*)0)) return NULL((void*)0);
1011
1012 for (symes = stabEntryAllSymes(stent); symes; symes = cdr(symes)((symes)->rest)) {
1013 Syme syme = car(symes)((symes)->first);
1014 if ((symeIsLexVar(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_LexVar)
|| symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
) &&
1015 symeDefLevel(syme) == car(stab)((stab)->first))
1016 return syme;
1017 }
1018
1019 return NULL((void*)0);
1020}
1021
1022/*
1023 * Get an export symbol meaning for id whose type is equal to tf modulo mods.
1024 */
1025Syme
1026stabGetExportMod(Stab stab, SymeList mods, Symbol id, TForm tf)
1027{
1028 StabEntry stent;
1029 SymeList symes;
1030
1031 if (stab == NULL((void*)0)) return NULL((void*)0);
1032
1033 stent = stabGetEntry(stab, id, true1);
1034 if (stent == NULL((void*)0)) return NULL((void*)0);
1035
1036 for (symes = stabEntryAllSymes(stent); symes; symes = cdr(symes)((symes)->rest)) {
1037 Syme syme = car(symes)((symes)->first);
1038
1039 if (!symeIsExport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Export)
) continue;
1040
1041 /*!! This should eventually be replaced by something which
1042 *!! knows how to compare the public parts of the types.
1043 */
1044 if (tfIsCategory(tf)(((tf)->tag) == TF_Category) && tfSatCat(symeType(syme)))
1045 return syme;
1046
1047 if (tformEqualMod(mods, tf, symeType(syme)))
1048 return syme;
1049 }
1050
1051 return NULL((void*)0);
1052}
1053
1054
1055/*
1056 * This function is a bit of a hack; it replaces stabGetExportMod,
1057 * iterating over only symbols in the local stab instead of doing
1058 * a recursive search.
1059 *
1060 * stabGetExportMod's remaining use is in tiWithSymes, and in those
1061 * contexts a recursive search seems to be necessary.
1062 *
1063 * Ideally, we'd replace both with a single function, but better to
1064 * commit this and gather test cases.
1065 */
1066
1067Syme
1068stabGetDomainExportMod(Stab astab, SymeList mods, Symbol sym, TForm tf)
1069{
1070 SymeList exports = stabGetExportedSymes(astab);
1071 while (exports != listNil(Syme)((SymeList) 0)) {
1072 Syme syme = car(exports)((exports)->first);
1073 exports = cdr(exports)((exports)->rest);
1074 if (symeId(syme)((syme)->id) != sym)
1075 continue;
1076 if (!symeIsExport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Export)
) continue;
1077 if (tfIsCategory(tf)(((tf)->tag) == TF_Category) && tfSatCat(symeType(syme)))
1078 return syme;
1079 if (tformEqualMod(mods, tf, symeType(syme)))
1080 return syme;
1081 }
1082 return NULL((void*)0);
1083}
1084
1085
1086
1087/*
1088 *
1089 */
1090Bool
1091stabGetLex(Stab stab, Symbol sym)
1092{
1093 return stabGetSymeOfKind(stab, sym, SYME_LexVar) != NULL((void*)0) ||
1094 stabGetSymeOfKind(stab, sym, SYME_LexConst) != NULL((void*)0);
1095}
1096
1097/*
1098 * Get the library symbol meaning for the given identifier.
1099 */
1100Syme
1101stabGetLibrary(Symbol sym)
1102{
1103 return stabGetSymeOfKind(stabFile(), sym, SYME_Library);
1104}
1105
1106/*
1107 * Get the archive symbol meaning for the given identifier.
1108 */
1109Syme
1110stabGetArchive(Symbol sym)
1111{
1112 return stabGetSymeOfKind(stabFile(), sym, SYME_Archive);
1113}
1114
1115/*
1116 * Get the first syme we find for the sym that has one of the given tags.
1117 */
1118localstatic Syme
1119stabGetSymeOfKind(Stab stab, Symbol sym, SymeTag tag)
1120{
1121 Syme syme = NULL((void*)0);
1122
1123 for (; !syme && stab; stab = cdr(stab)((stab)->rest))
1124 syme = stabLevelGetSymeOfKind(stab, sym, tag);
1125
1126 return syme;
1127}
1128
1129localstatic Syme
1130stabLevelGetSymeOfKind(Stab stab, Symbol sym, SymeTag tag)
1131{
1132 StabEntry stent = (StabEntry) tblElt(car(stab)((stab)->first)->tbl, sym, NULL((void*)0));
1133 SymeList symes = stent ? stabEntryAllSymes(stent) : listNil(Syme)((SymeList) 0);
1134
1135 for (; symes; symes = cdr(symes)((symes)->rest))
1136 if (symeKind(car(symes))((((((symes)->first))->kind == SYME_Trigger ? libGetAllSymes
((((symes)->first))->lib) : ((void*)0)), (((symes)->
first)))->kind)
== tag)
1137 return car(symes)((symes)->first);
1138 return NULL((void*)0);
1139}
1140
1141/******************************************************************************
1142 *
1143 * :: Symbol meaning creation
1144 *
1145 *****************************************************************************/
1146
1147void
1148stabUseMeaning(Stab stab, Syme syme)
1149{
1150 UShort d = stabLevelNo(stab)(((stab)->first)->lexicalLevel) - symeDefLevelNo(syme)(symeDefLevel(syme)->lexicalLevel);
1151
1152 if (DEBUG(stab)stabDebug) {
1153 fprintf(dbOut, "Using %s (.%ld) of depth %d at %d",
1154 symeString(syme)((((syme)->id))->str), symeConstNum(syme)(((AInt) (SYFI_ConstInfo < (8 * sizeof(int)) && !(
((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_ConstInfo
))) ? (symeFieldInfo[SYFI_ConstInfo].def) : (((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_ConstInfo)))
? ((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme
)->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_ConstInfo))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_ConstInfo
)] : (symeFieldInfo[SYFI_ConstInfo].def)) : symeGetFieldFn(syme
,SYFI_ConstInfo))) & 0xFFFF)
,
1155 symeUsedDepth(syme)((UShort) ((((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->locmask) & (1
<< (SYFI_UsedDepth))) ? ((syme)->fieldv)[symeIndex(
syme,SYFI_UsedDepth)] : (symeFieldInfo[SYFI_UsedDepth].def)))
, d);
1156 fnewline(dbOut);
1157 }
1158
1159 if (symeUnused(syme)(((UShort) ((((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->locmask) & (1
<< (SYFI_UsedDepth))) ? ((syme)->fieldv)[symeIndex(
syme,SYFI_UsedDepth)] : (symeFieldInfo[SYFI_UsedDepth].def)))
== (0x7FFF))
|| symeUsedDepth(syme)((UShort) ((((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->locmask) & (1
<< (SYFI_UsedDepth))) ? ((syme)->fieldv)[symeIndex(
syme,SYFI_UsedDepth)] : (symeFieldInfo[SYFI_UsedDepth].def)))
< d)
1160 symeSetUsedDepth(syme, d)(symeSetFieldVal = ((AInt) (d)), (((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
locmask) & (1 << (SYFI_UsedDepth))) ? (((syme)->
fieldv)[symeIndex(syme,SYFI_UsedDepth)] = (symeSetFieldVal)) :
!((syme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_UsedDepth].def) ? symeSetFieldVal : symeSetFieldFn(syme
,SYFI_UsedDepth,symeSetFieldVal))
;
1161}
1162
1163Bool
1164stabHasMeaning(Stab stab, Syme syme)
1165{
1166 StabEntry stent;
1167 SymeList symes;
1168 Bool result = false((int) 0);
1169
1170 for (; !result && stab; stab = cdr(stab)((stab)->rest)) {
1171 stent = (StabEntry) tblElt(car(stab)((stab)->first)->tbl, symeId(syme)((syme)->id), NULL((void*)0));
1172 symes = stent ? stabEntryAllSymes(stent) : listNil(Syme)((SymeList) 0);
1173 result = listMemq(Syme)(Syme_listPointer->Memq)(symes, syme);
1174 }
1175
1176 return result;
1177}
1178
1179Syme
1180stabAddMeaning(Stab stab, Syme syme)
1181{
1182 Symbol id;
1183 StabEntry stent;
1184
1185 assert(stab != 0)do { if (!(stab != 0)) _do_assert(("stab != 0"),"stab.c",1185
); } while (0)
;
1186
1187 if (stabLevelIsLocked(stab)(((stab)->first)->isLocked))
1188 return stabAddMeaning(cdr(stab)((stab)->rest), syme);
1189
1190 if (stabHasMeaning(stab, syme))
1191 return syme;
1192
1193 id = symeId(syme)((syme)->id);
1194
1195 switch (symeKind(syme)((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind)
) {
1196 case SYME_LexVar:
1197 case SYME_Param:
1198 case SYME_Extend:
1199 stent = stabGetEntry(stab, id, false((int) 0));
1200 break;
1201 default:
1202 stent = stabGetEntry(stab, id, true1);
1203 break;
1204 }
1205
1206 if (symeIsImportOfExtend(syme)((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Import) &&
(((((symeOriginal(syme))->kind == SYME_Trigger ? libGetAllSymes
((symeOriginal(syme))->lib) : ((void*)0)), (symeOriginal(syme
)))->kind) == SYME_Extend))
)
1207 symeRefreshExtendees(syme);
1208
1209 if (stent) {
1210 SymeList osymes = stabEntryAllSymes(stent);
1211 Syme osyme;
1212
1213 osyme = symeListHasImportee(osymes, syme);
1214 if (osyme)
1215 return osyme;
1216
1217 osyme = symeListHasExtendee(osymes, syme);
1218 if (osyme) {
1219 symeSetExtension(osyme, syme)symeXSetExtension(osyme, (AInt) syme);
1220 stabExtendMeanings(stab, syme);
1221 return syme;
1222 }
1223
1224 osyme = symeListHasExtension(osymes, syme);
1225 if (osyme)
1226 return osyme;
1227 }
1228
1229 car(stab)((stab)->first)->boundSymes = listCons(Syme)(Syme_listPointer->Cons)(syme, car(stab)((stab)->first)->boundSymes);
1230 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, "Adding stab entry %d %pSyme %pAbSynList\n", car(stab)((stab)->first)->lexicalLevel,
1231 syme, symeCondition(syme));
1232 stabEntryAddSyme(stent, syme);
1233
1234 return syme;
1235}
1236
1237void
1238stabPutMeaningSet(Stab stab, SymeSet symeSet)
1239{
1240 stabPutMeanings(stab, symeSetList(symeSet));
1241}
1242
1243void
1244stabPutMeanings(Stab stab, SymeList symes)
1245{
1246 SymeList l;
1247
1248 for (l = symes; l; l = cdr(l)((l)->rest)) {
1249 Syme syme = car(l)((l)->first);
1250
1251 stabAddMeaning(stab, syme);
1252 symeSetDefLevel(syme, car(stab)((stab)->first));
1253 }
1254}
1255
1256Syme
1257stabDefParam(Stab stab, Symbol id, TForm tform)
1258{
1259 Syme syme = symeNewParam(id, tform, car(stab)((stab)->first));
1260
1261 syme = stabAddMeaning(stab, syme);
1262 return syme;
1263}
1264
1265Syme
1266stabDefLexConst(Stab stab, Symbol id, TForm tform)
1267{
1268 Syme syme = symeNewLexConst(id, tform, car(stab)((stab)->first));
1269 symeSetDefnNum(syme, (int) ++stabDefinitionCounter)(symeSetFieldVal = ((AInt) ((int) ++stabDefinitionCounter)), (
((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_DefnNum
))) ? (((syme)->fieldv)[symeIndex(syme,SYFI_DefnNum)] = (symeSetFieldVal
)) : !((syme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefnNum].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_DefnNum
,symeSetFieldVal))
;
1270
1271 if (DEBUG(stabConst)stabConstDebug) {
1272 fprintf(dbOut, "defnNum[%d]: ", symeDefnNum(syme)((int) (SYFI_DefnNum < (8 * sizeof(int)) && !(((((
syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->lib
) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_DefnNum
))) ? (symeFieldInfo[SYFI_DefnNum].def) : (((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_DefnNum))) ?
((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)
->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_DefnNum))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_DefnNum
)] : (symeFieldInfo[SYFI_DefnNum].def)) : symeGetFieldFn(syme
,SYFI_DefnNum)))
);
1273 symePrint(dbOut, syme);
1274 fnewline(dbOut);
1275 }
1276
1277 syme = stabAddMeaning(stab, syme);
1278 return syme;
1279}
1280
1281Syme
1282stabDefLexVar(Stab stab, Symbol id, TForm tform)
1283{
1284 Syme syme = symeNewLexVar(id, tform, car(stab)((stab)->first));
1285
1286 syme = stabAddMeaning(stab, syme);
1287 symeSetDefnNum(syme, (int) ++stabDefinitionCounter)(symeSetFieldVal = ((AInt) ((int) ++stabDefinitionCounter)), (
((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_DefnNum
))) ? (((syme)->fieldv)[symeIndex(syme,SYFI_DefnNum)] = (symeSetFieldVal
)) : !((syme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefnNum].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_DefnNum
,symeSetFieldVal))
;
1288
1289 if (DEBUG(stabConst)stabConstDebug) {
1290 fprintf(dbOut, "defnNum[%d]: ", symeDefnNum(syme)((int) (SYFI_DefnNum < (8 * sizeof(int)) && !(((((
syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->lib
) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_DefnNum
))) ? (symeFieldInfo[SYFI_DefnNum].def) : (((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_DefnNum))) ?
((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)
->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_DefnNum))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_DefnNum
)] : (symeFieldInfo[SYFI_DefnNum].def)) : symeGetFieldFn(syme
,SYFI_DefnNum)))
);
1291 symePrint(dbOut, syme);
1292 fnewline(dbOut);
1293 }
1294
1295 return syme;
1296}
1297
1298Syme
1299stabDefFluid(Stab stab, Symbol id, TForm tform)
1300{
1301 Syme syme = symeNewFluid(id, tform, car(stab)((stab)->first));
1302
1303 syme = stabAddMeaning(stab, syme);
1304
1305 return syme;
1306}
1307
1308Syme
1309stabDefImport(Stab stab, Symbol id, TForm tform, TForm exporter)
1310{
1311 Syme syme = symeNewImport(id, tform, car(stab)((stab)->first), exporter);
1312
1313 return stabAddMeaning(stab, syme);
1314}
1315
1316Syme
1317stabDefExport(Stab stab, Symbol id, TForm tform, Doc doc)
1318{
1319 Syme syme = symeNewExport(id, tform, car(stab)((stab)->first));
1320
1321 if (DEBUG(stab)stabDebug) {
1322 fprintf(dbOut, "Defining export %s with comment ",
1323 symString(id)((id)->str));
1324 docPrint(dbOut, doc);
1325 fnewline(dbOut);
1326 }
1327
1328 symeSetComment(syme, doc)(symeSetFieldVal = ((AInt) (doc)), (((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
locmask) & (1 << (SYFI_Comment))) ? (((syme)->fieldv
)[symeIndex(syme,SYFI_Comment)] = (symeSetFieldVal)) : !((syme
)->full) && symeSetFieldVal == (symeFieldInfo[SYFI_Comment
].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_Comment,symeSetFieldVal
))
;
1329 syme = stabAddMeaning(stab, syme);
1330 symeSetDefnNum(syme, (int) ++stabDefinitionCounter)(symeSetFieldVal = ((AInt) ((int) ++stabDefinitionCounter)), (
((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_DefnNum
))) ? (((syme)->fieldv)[symeIndex(syme,SYFI_DefnNum)] = (symeSetFieldVal
)) : !((syme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefnNum].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_DefnNum
,symeSetFieldVal))
;
1331
1332 if (DEBUG(stabConst)stabConstDebug) {
1333 fprintf(dbOut, "defnNum[%d]: ", symeDefnNum(syme)((int) (SYFI_DefnNum < (8 * sizeof(int)) && !(((((
syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->lib
) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_DefnNum
))) ? (symeFieldInfo[SYFI_DefnNum].def) : (((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_DefnNum))) ?
((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)
->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_DefnNum))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_DefnNum
)] : (symeFieldInfo[SYFI_DefnNum].def)) : symeGetFieldFn(syme
,SYFI_DefnNum)))
);
1334 symePrint(dbOut, syme);
1335 fnewline(dbOut);
1336 }
1337
1338 return syme;
1339}
1340
1341Syme
1342stabDefExtendee(Stab stab, Symbol id, TForm tform, Doc doc)
1343{
1344 Syme syme = symeNewExport(id, tform, car(stab)((stab)->first));
1345
1346 symeSetComment(syme, doc)(symeSetFieldVal = ((AInt) (doc)), (((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
locmask) & (1 << (SYFI_Comment))) ? (((syme)->fieldv
)[symeIndex(syme,SYFI_Comment)] = (symeSetFieldVal)) : !((syme
)->full) && symeSetFieldVal == (symeFieldInfo[SYFI_Comment
].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_Comment,symeSetFieldVal
))
;
1347 symeSetDefnNum(syme, (int) ++stabDefinitionCounter)(symeSetFieldVal = ((AInt) ((int) ++stabDefinitionCounter)), (
((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_DefnNum
))) ? (((syme)->fieldv)[symeIndex(syme,SYFI_DefnNum)] = (symeSetFieldVal
)) : !((syme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefnNum].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_DefnNum
,symeSetFieldVal))
;
1348
1349 return syme;
1350}
1351
1352Syme
1353stabDefExtend(Stab stab, Symbol id, TForm tform)
1354{
1355 Syme syme = symeNewExtend(id, tform, car(stab)((stab)->first));
1356
1357 return stabAddMeaning(stab, syme);
1358}
1359
1360Syme
1361stabDefLibrary(Stab stab, Symbol id, TForm tform, Lib lib)
1362{
1363 SymeList symes;
1364 Syme syme;
1365
1366 /* Check for symbol meanings that already exist. */
1367 symes = stabGetMeanings(stab, NULL((void*)0), id);
1368 if (symes) {
1369 comsgWarning(NULL((void*)0), ALDOR_W_LibRedefined153, symString(id)((id)->str));
1370 return car(symes)((symes)->first);
1371 }
1372
1373 syme = symeNewLibrary(id, tform, car(stab)((stab)->first), lib);
1374 tfFrSyme(stab, syme);
1375
1376 return stabAddMeaning(stab, syme);
1377}
1378
1379Syme
1380stabDefArchive(Stab stab, Symbol id, TForm tform, Archive ar)
1381{
1382 SymeList symes;
1383 Syme syme;
1384
1385 /* Check for symbol meanings that already exist. */
1386 symes = stabGetMeanings(stab, NULL((void*)0), id);
1387 if (symes) {
1388 comsgWarning(NULL((void*)0), ALDOR_W_LibRedefined153, symString(id)((id)->str));
1389 return car(symes)((symes)->first);
1390 }
1391
1392 syme = symeNewArchive(id, tform, car(stab)((stab)->first), ar);
1393 tfFrSyme(stab, syme);
1394
1395 return stabAddMeaning(stab, syme);
1396}
1397
1398Syme
1399stabDefForeign(Stab stab, Symbol id, TForm tform, ForeignOrigin forg)
1400{
1401 Syme syme = symeNewForeign(id, tform, car(stab)((stab)->first), forg);
1402
1403 return stabAddMeaning(stab, syme);
1404}
1405
1406Syme
1407stabDefBuiltin(Stab stab, Symbol id, TForm tform, FoamBValTag builtin)
1408{
1409 Syme syme = symeNewBuiltin(id, tform, car(stab)((stab)->first), builtin);
1410
1411 return stabAddMeaning(stab, syme);
1412}
1413
1414/******************************************************************************
1415 *
1416 * :: Shadow Stuff
1417 *
1418 *****************************************************************************/
1419
1420static AbSyn StabUseMeaningShadow = 0;
1421
1422void
1423stabUseMeaningShadow(AbSyn ab)
1424{
1425 StabUseMeaningShadow = ab;
1426}
1427
1428void
1429stabUseMeaningUnshadow(void)
1430{
1431 StabUseMeaningShadow = 0;
1432}
1433
1434void
1435stabSetSyme(Stab stab, AbSyn ab, Syme syme, AbLogic cond)
1436{
1437 SImpl impl;
1438 /*!! if (abUse(ab) != AB_Use_Declaration &&
1439 abUse(ab) != AB_Use_Define) */
1440 if (ab != StabUseMeaningShadow)
1441 stabUseMeaning(stab, syme);
1442 abSetSyme(ab, syme);
1443
1444 if (abDefineIdx(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->defnIdx : -1
)
!= -1)
1445 symeImplAddConst(syme, cond, abDefineIdx(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->defnIdx : -1
)
);
1446
1447 /* NB: We assume that the impl information is correct.
1448 * It ought to be, at least for add bodies, 'cos it is
1449 * set in tiAddSymes.
1450 */
1451 impl = implEvaluate(symeImpl(syme)((SImpl) (SYFI_SImpl < (8 * sizeof(int)) && !(((((
syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->lib
) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_SImpl
))) ? (symeFieldInfo[SYFI_SImpl].def) : (((((syme)->kind ==
SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0)),
(syme))->locmask) & (1 << (SYFI_SImpl))) ? ((((
((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_SImpl
))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_SImpl)] : (symeFieldInfo
[SYFI_SImpl].def)) : symeGetFieldFn(syme,SYFI_SImpl)))
, abCondKnown);
1452 abSetImpl(ab, impl);
1453}
1454
1455Bool
1456stabIsUndeclaredId(Stab stab, Symbol sym)
1457{
1458 Length symec = 0;
1459 SymeList symes;
1460
1461 for (symes = stabGetMeanings(stab, NULL((void*)0), sym); symes; symes = cdr(symes)((symes)->rest))
1462 if (tfIsUnknown(symeType(car(symes)))(((symeType(((symes)->first)))->tag) == TF_Unknown))
1463 symec += 1;
1464
1465 return symec == 1;
1466}
1467
1468void
1469stabDeclareId(Stab stab, Symbol sym, TForm tform)
1470{
1471 Syme syme = NULL((void*)0);
1
'syme' initialized to a null pointer value
1472 SymeList symes;
1473
1474 for (symes = stabGetMeanings(stab, NULL((void*)0), sym); symes; symes = cdr(symes)((symes)->rest))
2
Loop condition is false. Execution continues on line 1478
1475 if (tfIsUnknown(symeType(car(symes)))(((symeType(((symes)->first)))->tag) == TF_Unknown))
1476 syme = car(symes)((symes)->first);
1477
1478 assert(syme)do { if (!(syme)) _do_assert(("syme"),"stab.c",1478); } while
(0)
;
3
Taking true branch
4
Loop condition is false. Exiting loop
1479 symeSetType(syme, tform);
1480 stabPropagateDecl(stab, syme);
5
Passing null pointer value via 2nd parameter 'syme'
6
Calling 'stabPropagateDecl'
1481}
1482
1483/* Once the type of syme has been inferred,
1484 * clear the stab entry caches for each level in which syme is visible.
1485 * Ex: for x in 1..10
1486 * j := 1 -- declared here
1487 * j := 2 -- update this stent
1488 */
1489localstatic void
1490stabPropagateDecl(Stab stab, Syme syme)
1491{
1492 StabEntry stent;
1493 Symbol sym = symeId(syme)((syme)->id);
7
Access to field 'id' results in a dereference of a null pointer (loaded from variable 'syme')
1494
1495 for (; stab; stab = cdr(stab)((stab)->rest)) {
1496 stent = (StabEntry) tblElt(car(stab)((stab)->first)->tbl, sym, NULL((void*)0));
1497
1498 if (stent && listMemq(Syme)(Syme_listPointer->Memq)(stabEntryAllSymes(stent), syme))
1499 stabEntryClearCache(stent);
1500
1501 /* Stop when the definition level has been reached. */
1502 if (car(stab)((stab)->first) == symeDefLevel(syme)) break;
1503 }
1504}
1505/******************************************************************************
1506 *
1507 * :: Symbol table printing.
1508 *
1509 *****************************************************************************/
1510
1511int
1512stabPrint(FILE * fout, Stab stab)
1513{
1514 return stabPrintTo(fout, stab, (int) 0);
1515}
1516
1517/*
1518 * Print "stab" level by level until "minlev" is reached. If "minlev" is
1519 * negative, then the count is made from the top of the stack instead of the
1520 * bottom.
1521 */
1522
1523int
1524stabPrintTo(FILE * fout, Stab stab, int minlev)
1525{
1526 int cc, ts;
1527 StabLevel slev;
1528
1529 if (stab && minlev < 0)
1530 minlev = car(stab)((stab)->first)->lexicalLevel + minlev + 1;
1531
1532 for (cc = 0; stab; stab = cdr(stab)((stab)->rest)) {
1533 slev = car(stab)((stab)->first);
1534 if (slev->lexicalLevel < minlev)
1535 break;
1536 cc += fnewline(fout);
1537 cc += fprintf(fout, "SymbolTable Level %ld, %s, (serial %ld),",
1538 slev->lexicalLevel,
1539 stabLevelIsLarge(stab)(((stab)->first)->tformsUsed.table) ? "LARGE" : "SMALL",
1540 slev->serialNo);
1541 cc += fprintf(fout, " %d symbols.", ts = tblSize(slev->tbl));
1542 findent += 2;
1543 cc += fnewline(fout);
1544 if (ts)
1545 cc += tblColumnPrint(fout, slev->tbl,
1546 (TblPrKeyFun) 0, stabPrEntry);
1547 findent -= 2;
1548 cc += fnewline(fout);
1549
1550 if (slev->tformsUnused) {
1551 TFormList tfl;
1552
1553 cc += fprintf(fout,
1554 "Type forms registered but not used: ");
1555 findent += 2;
1556 cc += fnewline(fout);
1557 for (tfl = slev->tformsUnused; tfl; tfl = cdr(tfl)((tfl)->rest)) {
1558 cc += tfPrint(fout, car(tfl)((tfl)->first));
1559 cc += fnewline(fout);
1560 }
1561 findent -= 2;
1562 cc += fnewline(fout);
1563 }
1564
1565 cc += fprintf(fout, "All type forms used: ");
1566 findent += 2;
1567 cc += fnewline(fout);
1568
1569 if (!slev->tformsUsed.list)
1570 cc += fprintf(fout, "NONE");
1571 else
1572 cc += tfulPrint(fout, slev->tformsUsed.list);
1573
1574 findent -= 2;
1575 cc += fnewline(fout);
1576
1577 if (slev->labelsInScope) {
1578 AbSynList asl = slev->labelsInScope;
1579 cc += fprintf(fout, "Labels in this scope: ");
1580 while (asl) {
1581 cc += abPrettyPrint(fout, car(asl)((asl)->first));
1582 asl = cdr(asl)((asl)->rest);
1583 cc += asl ? fprintf(fout, ", ") : fnewline(fout);
1584 }
1585 cc += fnewline(fout);
1586 }
1587
1588 if (slev->boundSymes) {
1589 SymeList sl = slev->boundSymes;
1590 cc += fprintf(fout, "Bound symbol meanings: ");
1591 findent += 2;
1592 cc += fnewline(fout);
1593 while (sl) {
1594 cc += symePrint(fout, car(sl)((sl)->first));
1595 sl = cdr(sl)((sl)->rest);
1596 if (sl)
1597 cc += fnewline(fout);
1598 }
1599 findent -= 2;
1600 }
1601
1602 cc += fnewline(fout);
1603 }
1604 return cc;
1605}
1606
1607localstatic int
1608stabPrEntry(FILE * fout, TblElt e)
1609{
1610 StabEntry stent = (StabEntry) e;
1611 SymeList symes = stabEntryAllSymes(stent);
1612 int cc = 0;
1613
1614 for (; symes; symes = cdr(symes)((symes)->rest)) {
1615 cc += symePrint(fout, car(symes)((symes)->first));
1616 if (cdr(symes)((symes)->rest))
1617 cc += fnewline(fout);
1618 }
1619 return cc;
1620}
1621
1622int
1623tfulPrint(FILE *fout, TFormUsesList tful)
1624{
1625 int cc = 0;
1626 while (tful) {
1627 TFormUses tfu = car(tful)((tful)->first);
1628 tful = cdr(tful)((tful)->rest);
1629 cc += tfuPrint(fout, tfu);
1630 }
1631 return cc;
1632}
1633
1634int
1635tfuPrint(FILE *fout, TFormUses tfu)
1636{
1637 int cc = 0;
1638
1639 cc += tfPrint(fout, tfu->tf);
1640 findent += 2;
1641 cc += fnewline(fout);
1642
1643 if (tfu->isExplicitImport) {
1644 cc += fprintf(fout, "Explicitly imported.");
1645 cc += fnewline(fout);
1646 }
1647 if (tfu->isCategoryImport) {
1648 cc += fprintf(fout, "Categorically imported.");
1649 cc += fnewline(fout);
1650 }
1651 if (tfu->isParamImport) {
1652 cc += fprintf(fout, "Parameter import.");
1653 cc += fnewline(fout);
1654 }
1655
1656 if (tfu->exports) {
1657 cc += fprintf(fout, "exports: ");
1658 cc += tqPrint(fout, tfu->exports);
1659 cc += fnewline(fout);
1660 }
1661 if (tfu->imports) {
1662 cc += fprintf(fout, "imports: ");
1663 cc += tqPrint(fout, tfu->imports);
1664 cc += fnewline(fout);
1665 }
1666 if (tfu->inlines) {
1667 cc += fprintf(fout, "inlines: ");
1668 cc += tqPrint(fout, tfu->inlines);
1669 cc += fnewline(fout);
1670 }
1671
1672 if (tfQueries(tfu->tf)((tfu->tf)->queries)) {
1673 TFormList cl;
1674 int i;
1675
1676 cc += fnewline(fout);
1677 cc += fprintf(fout, "Conditional categories:");
1678 cl = tfQueries(tfu->tf)((tfu->tf)->queries);
1679 findent += 2;
1680 cc += fnewline(fout);
1681 for (i = 1; cl; cl = cdr(cl)((cl)->rest), i++) {
1682 cc += fprintf(fout, "%d: ", i);
1683 cc += tformPrint(fout, car(cl)((cl)->first));
1684 cc += fnewline(fout);
1685 }
1686 findent -= 2;
1687 }
1688
1689 if (tfu->declarees) {
1690 cc += fnewline(fout);
1691 cc += fprintf(fout, "Declarees: ");
1692 listPrint(Symbol)(Symbol_listPointer->Print)(fout,tfu->declarees,symPrint);
1693 }
1694
1695 findent -= 2;
1696 cc += fnewline(fout);
1697
1698 return cc;
1699}
1700
1701/******************************************************************************
1702 *
1703 * :: Imports
1704 *
1705 *****************************************************************************/
1706
1707SymeList
1708stabGetExportedSymes(Stab stab)
1709{
1710 SymeList symes, exports = listNil(Syme)((SymeList) 0);
1711
1712 for (symes = stabGetBoundSymes(stab)(((stab)->first)->boundSymes); symes; symes = cdr(symes)((symes)->rest)) {
1713 Syme syme = car(symes)((symes)->first);
1714 if (symeIsExport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Export)
|| symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
)
1715 exports = listCons(Syme)(Syme_listPointer->Cons)(car(symes)((symes)->first), exports);
1716 }
1717
1718 return exports;
1719}
1720
1721TQualList
1722stabImportFrom(Stab stab, TQual tq)
1723{
1724 SymeSet dsymes;
1725 TForm origin = tqBase(tq)((tq)->base);
1726
1727
1728 /* Carefully follow this tform */
1729 tfFollow(origin)((origin) = tfFollowFn(origin));
1730
1731
1732 /*
1733 * We can significantly improve inlining if we replace
1734 * the domain with its normal form. Users can turn this
1735 * off by compiling with -Wdumb-import.
1736 */
1737 if (!stabDumbImport())
1738 {
1739 TForm base = tfDefineeBaseType(origin);
1740
1741 if (tfQueries(origin)((origin)->queries) != listNil(TForm)((TFormList) 0))
1742 (void)tfCopyQueries(base, origin);
1743 origin = base;
1744 }
1745
1746
1747 /* Don't import a tform if has already been imported */
1748 if (stabIsImportedTForm(stab, origin))
1749 return listNil(TQual)((TQualList) 0);
1750
1751 if (DEBUG(stabImport)stabImportDebug) {
1752 fprintf(dbOut, "Importing %s from ",
1753 tqIsForeign(tq)(((tq)->status) == TQUAL_Foreign) ? " foreign exports" :
1754 tqIsBuiltin(tq)(((tq)->status) == TQUAL_Builtin) ? " builtin exports" :
1755 tqIsQualified(tq)((tq)->isQual == 1) ? " explicit exports" : "");
1756 tfPrint(dbOut, origin);
1757 fnewline(dbOut);
1758 }
1759
1760 stabImportRemark(stab, tqQual(tq)((tq)->qual), origin);
1761
1762 if (tqIsForeign(tq)(((tq)->status) == TQUAL_Foreign))
1763 dsymes = symeSetFrSymes(tqGetForeignImports(stab, tq));
1764 else if (tqIsBuiltin(tq)(((tq)->status) == TQUAL_Builtin))
1765 dsymes = symeSetFrSymes(tqGetBuiltinImports(stab, tq));
1766 else if (tqIsQualified(tq)((tq)->isQual == 1))
1767 dsymes = symeSetFrSymes(tqGetQualImports(tq));
1768 else {
1769 Stab nstab = stab;
1770
1771 /*
1772 * We want to avoid using stabFile() otherwise some
1773 * tforms will seep into the top level and cause us
1774 * grief later on (e.g. bug1192). However, there are
1775 * times when we really do want to use stabFile(). If
1776 * we have sefo that isn't associated with any source
1777 * code then stabFile() ought to be okay.
1778 *
1779 * An alternative to using the local stab passed down
1780 * to us, we be to use tfStab() if it was present. That
1781 * may be more reliable if it corresponds to a higher
1782 * lexical level.
1783 */
1784 if (!tfGetExpr(origin)((origin)->__absyn) || !abPos(tfGetExpr(origin))(spstackFirst((((origin)->__absyn))->abHdr.pos)))
1785 nstab = stabFile();
1786
1787
1788 /* Get the domain imports of origin */
1789 dsymes = tfStabGetDomImportSet(nstab, origin);
1790
1791
1792 /*
1793 * It doesn't matter which stab we chose to get domain
1794 * imports from, we are importing into the local one.
1795 */
1796 if (!symeSetIsEmpty(dsymes)) stabMakeImportedTForm(stab, origin);
1797 }
1798
1799 stabPutMeaningSet(stab, dsymes);
1800
1801 stabImportDEBUGif (!stabImportDebug) { } else afprintf(dbOut, "... imported: %pSymeSet\n", dsymes);
1802
1803 if (!tqIsQualified(tq)((tq)->isQual == 1))
1804 return tfGetDomCascades(origin);
1805 else
1806 return listNil(TQual)((TQualList) 0);
1807}
1808
1809localstatic void
1810stabImportRemark(Stab stab, TFormList what, TForm origin)
1811{
1812 if (comsgOkRemark(ALDOR_R_StabImporting140)) {
1813 String s = tfPretty(origin);
1814 comsgRemark(abNewNothing(car(stab)->spos)abNew(AB_Nothing, ((stab)->first)->spos,0 ), ALDOR_R_StabImporting140, s);
1815 strFree(s);
1816 }
1817
1818 if (what && comsgOkRemark(ALDOR_R_StabImportingQual141)) {
1819 Buffer buf = bufNew();
1820 String explicits;
1821 TFormList tmpList;
1822
1823 for (tmpList = what; tmpList; tmpList = cdr(tmpList)((tmpList)->rest)) {
1824 String pp = abPretty(tfExpr(car(tmpList))tfToAbSyn(((tmpList)->first)));
1825 bufAdd1(buf, '\n');
1826 bufAdd1(buf, '\t');
1827 bufPuts(buf, pp);
1828 strFree(pp);
1829 }
1830
1831 explicits = bufLiberate(buf);
1832 comsgRemark(abNewNothing(car(stab)->spos)abNew(AB_Nothing, ((stab)->first)->spos,0 ),
1833 ALDOR_R_StabImportingQual141, explicits);
1834
1835 strFree(explicits);
1836 }
1837}
1838
1839/******************************************************************************
1840 *
1841 * :: Foreign exports
1842 *
1843 *****************************************************************************/
1844
1845void
1846stabAddForeignExport(Stab stab, TForm tf, ForeignOrigin forg)
1847{
1848 if (car(stab)((stab)->first)->exportedTypes == NULL((void*)0))
1849 car(stab)((stab)->first)->exportedTypes = tblNew((TblHashFun) tfHash, (TblEqFun) tfEqual);
1850 tblSetElt(car(stab)((stab)->first)->exportedTypes, tf, forg);
1851}
1852
1853ForeignOrigin
1854stabForeignExportLocation(Stab stab, TForm tf)
1855{
1856 while (stab != listNil(StabLevel)((StabLevelList) 0)) {
1857 if (car(stab)((stab)->first)->exportedTypes == NULL((void*)0)) {
1858 stab = cdr(stab)((stab)->rest);
1859 continue;
1860 }
1861 ForeignOrigin forg = tblElt(car(stab)((stab)->first)->exportedTypes, tf, NULL((void*)0));
1862 if (forg != NULL((void*)0))
1863 return forg;
1864 stab = cdr(stab)((stab)->rest);
1865 }
1866 return NULL((void*)0);
1867}
1868
1869Bool
1870stabIsForeignExport(Stab stab, TForm tf)
1871{
1872 return stabForeignExportLocation(stab, tf) != NULL((void*)0);
1873}
1874
1875/****************************************************************************
1876 *
1877 * TForm and TFormUses code.
1878 *
1879 ****************************************************************************/
1880
1881/*
1882 * General scheme is this: TFormUses holds TForms and their usage
1883 * information. If a TForm is "registered" via stabDefTForm but not
1884 * used explicitly yet for importing or inlining, say, then it is stored on
1885 * the list tformsUnused. A TForm is taken off that list when it is
1886 * added to tformsUsed.
1887 */
1888
1889localstatic TFormUses
1890tformDoNothing(TFormUses tfu)
1891{
1892 /*
1893 * Used to return an old or newly created TFormUses object.
1894 */
1895 return tfu;
1896}
1897
1898localstatic TFormUses
1899tformIsImported(TFormUses tfu)
1900{
1901 tfu->isImported = true1;
1902 return tfu;
1903}
1904
1905localstatic TFormUses
1906tformExportAll(TFormUses tfu)
1907{
1908 tfuSetUnqualified(tfu->exports, tfu->tf)((tfu->exports) = (tfu->exports) ? tqSetUnqualified(tfu
->exports) : tqNewUnqualified(tfu->tf))
;
1909 return tfu;
1910}
1911
1912localstatic TFormUses
1913tformImportAll(TFormUses tfu)
1914{
1915 tfuSetUnqualified(tfu->imports, tfu->tf)((tfu->imports) = (tfu->imports) ? tqSetUnqualified(tfu
->imports) : tqNewUnqualified(tfu->tf))
;
1916 return tfu;
1917}
1918
1919localstatic TFormUses
1920tformInlineAll(TFormUses tfu)
1921{
1922 tfuSetUnqualified(tfu->inlines, tfu->tf)((tfu->inlines) = (tfu->inlines) ? tqSetUnqualified(tfu
->inlines) : tqNewUnqualified(tfu->tf))
;
1923 return tfu;
1924}
1925
1926localstatic TFormUses
1927tformExplicitlyImportAll(TFormUses tfu)
1928{
1929 tfu->isExplicitImport = true1;
1930 return tformImportAll(tfu);
1931}
1932
1933localstatic TFormUses
1934tformCategoricallyImport(TFormUses tfu)
1935{
1936 tfu->isCategoryImport = true1;
1937 return tfu;
1938}
1939
1940localstatic TFormUses
1941tformCatConditionImport(TFormUses tfu)
1942{
1943 tfu->isCatConditionImport = true1;
1944 return tfu;
1945}
1946
1947localstatic TFormUses
1948tformParameterImport(TFormUses tfu)
1949{
1950 tfu->isParamImport = true1;
1951 return tfu;
1952}
1953
1954localstatic TFormUses
1955tfuNew(TForm tf)
1956{
1957 TFormUses tu = (TFormUses) stoAlloc(OB_Other0, sizeof(*tu));
1958
1959 tu->isImported = false((int) 0);
1960 tu->isExplicitImport = false((int) 0);
1961 tu->isCategoryImport = false((int) 0);
1962 tu->isCatConditionImport= false((int) 0);
1963 tu->isParamImport = false((int) 0);
1964 tu->tf = tf;
1965 tu->exports = NULL((void*)0);
1966 tu->imports = NULL((void*)0);
1967 tu->inlines = NULL((void*)0);
1968 tu->cascades = listNil(TQual)((TQualList) 0);
1969 tu->extension = listNil(AbSyn)((AbSynList) 0);
1970 tu->extendees = listNil(AbSyn)((AbSynList) 0);
1971 tu->declarees = listNil(Symbol)((SymbolList) 0);
1972 tu->dependents = listNil(TFormUses)((TFormUsesList) 0);
1973 tu->dependees = listNil(TFormUses)((TFormUsesList) 0);
1974 tu->nbefore = 0;
1975 tu->nafter = 0;
1976 tu->cdependents = listNil(TFormUses)((TFormUsesList) 0);
1977 tu->cdependees = listNil(TFormUses)((TFormUsesList) 0);
1978 tu->ncbefore = 0;
1979 tu->ncafter = 0;
1980 tu->sortMark = false((int) 0);
1981 tu->outEdges = listNil(TFormUses)((TFormUsesList) 0);
1982 tu->inDegree = 0;
1983 tu->cmarked = false((int) 0);
1984 tu->crep = NULL((void*)0);
1985
1986 return tu;
1987}
1988
1989TFormUses
1990stabFindTFormUses(Stab stab, AbSyn ab)
1991{
1992 TFormUses tfu = NULL((void*)0);
1993 TFormUsesList tful;
1994
1995 assert(stab != 0)do { if (!(stab != 0)) _do_assert(("stab != 0"),"stab.c",1995
); } while (0)
;
1996 assert(ab != 0)do { if (!(ab != 0)) _do_assert(("ab != 0"),"stab.c",1996); }
while (0)
;
1997
1998 if (stabUseList(stab, ab)!(((stab)->first)->tformsUsed.table)) {
1999 tful = car(stab)((stab)->first)->tformsUsed.list;
2000 for (; tful && !tfu; tful = cdr(tful)((tful)->rest))
2001 if (abEqual(ab, tfGetExpr(car(tful)->tf)((((tful)->first)->tf)->__absyn)))
2002 tfu = car(tful)((tful)->first);
2003 }
2004 else if (stabUseTable(stab, ab)(((stab)->first)->tformsUsed.table))
2005 tfu = (TFormUses) tblElt(car(stab)((stab)->first)->tformsUsed.table,
2006 (TblKey) ab, (TblElt) NULL((void*)0));
2007
2008 return tfu;
2009}
2010
2011/*
2012 * Find or create a TFormUses and then call fun on it
2013 */
2014localstatic TFormUses
2015tfuSetFlag(Stab stab, TForm tf, UpdateTfuFun fun)
2016{
2017 AbSyn ab = tfExpr(tf)tfToAbSyn(tf);
2018 TFormUses tfu = stabFindTFormUses(stab, ab);
2019
2020 if (!tfu) {
2021 /* first remove tf from tformsUnused, if present */
2022 removeTFormUnused(stab, tf);
2023
2024 /* now make a new one */
2025 tfu = tfuNew(tf);
2026
2027 if (stabUseTable(stab, ab)(((stab)->first)->tformsUsed.table))
2028 tblSetElt(car(stab)((stab)->first)->tformsUsed.table,
2029 (TblKey) ab, (TblElt) tfu);
2030 listPush(TFormUses, tfu, car(stab)->tformsUsed.list)(((stab)->first)->tformsUsed.list = (TFormUses_listPointer
->Cons)(tfu, ((stab)->first)->tformsUsed.list))
;
2031 }
2032
2033 return fun(tfu);
2034}
2035
2036localstatic TForm
2037findTFormUnused(Stab stab, AbSyn ab)
2038{
2039 TFormList tfl;
2040
2041 for (tfl = car(stab)((stab)->first)->tformsUnused; tfl; tfl = cdr(tfl)((tfl)->rest))
2042 if (abEqual(ab, tfGetExpr(car(tfl))((((tfl)->first))->__absyn)))
2043 return car(tfl)((tfl)->first);
2044
2045 return 0;
2046}
2047
2048localstatic TForm
2049addTFormUnused(Stab stab, TForm tf)
2050{
2051 car(stab)((stab)->first)->tformsUnused =
2052 listCons(TForm)(TForm_listPointer->Cons) (tf, car(stab)((stab)->first)->tformsUnused);
2053 return tf;
2054}
2055
2056localstatic void
2057removeTFormUnused(Stab stab, TForm tf)
2058{
2059 car(stab)((stab)->first)->tformsUnused =
2060 listNRemove(TForm)(TForm_listPointer->NRemove) (car(stab)((stab)->first)->tformsUnused, tf, tfEqual);
2061}
2062
2063TForm
2064stabMakeUsedTForm(Stab stab, AbSyn ab, TfCondElt conditions)
2065{
2066 TFormUses tfu;
2067 TForm tf;
2068
2069 tfu = stabFindTFormUses(stab, ab);
2070 if (tfu == NULL((void*)0)) {
2071 tf = tfSyntaxFrAbSyn(stab, ab);
2072 tfu = tfuSetFlag(stab, tf, tformDoNothing);
2073 }
2074 else {
2075 tf = tfu->tf;
2076 }
2077
2078 tfSyntaxConditions(stab, tf, conditions);
2079 abSetTForm(ab, tf);
2080 return tf;
2081}
2082
2083TForm
2084stabMakeImportedTForm(Stab stab, TForm tf)
2085{
2086 return tfuSetFlag(stab, tf, tformIsImported)->tf;
2087}
2088
2089TForm
2090stabExportTForm(Stab stab, TForm tf)
2091{
2092 return tfuSetFlag(stab, tf, tformExportAll)->tf;
2093}
2094
2095TForm
2096stabImportTForm(Stab stab, TForm tf)
2097{
2098 return tfuSetFlag(stab, tf, tformImportAll)->tf;
2099}
2100
2101TForm
2102stabInlineTForm(Stab stab, TForm tf)
2103{
2104 return tfuSetFlag(stab, tf, tformInlineAll)->tf;
2105}
2106
2107TForm
2108stabExplicitlyImportTForm(Stab stab, TForm tf)
2109{
2110 return tfuSetFlag(stab, tf, tformExplicitlyImportAll)->tf;
2111}
2112
2113TForm
2114stabCategoricallyImportTForm(Stab stab, TForm tf)
2115{
2116 return tfuSetFlag(stab, tf, tformCategoricallyImport)->tf;
2117}
2118
2119TForm
2120stabParameterImportTForm(Stab stab, TForm tf)
2121{
2122 return tfuSetFlag(stab, tf, tformParameterImport)->tf;
2123}
2124
2125TForm
2126stabQualifiedExportTForm(Stab stab, AbSyn ab, TForm tf)
2127{
2128 TFormUses tfu = tfuSetFlag(stab, tf, tformDoNothing);
2129
2130 tfuSetQualified(tfu->exports, tfu->tf, tfSyntaxFrAbSyn(stab, ab))((tfu->exports) = (tfu->exports) ? (((tfu->exports)->
isQual == 1) ? tqAddQual(tfu->exports,tfSyntaxFrAbSyn(stab
, ab)) : (tfu->exports)) : tqNewQualified(tfu->tf,tfSyntaxFrAbSyn
(stab, ab)))
;
2131
2132 return tf;
2133}
2134
2135TForm
2136stabQualifiedImportTForm(Stab stab, AbSyn ab, TForm tf)
2137{
2138 TFormUses tfu = tfuSetFlag(stab, tf, tformDoNothing);
2139
2140 tfuSetQualified(tfu->imports, tfu->tf, tfSyntaxFrAbSyn(stab, ab))((tfu->imports) = (tfu->imports) ? (((tfu->imports)->
isQual == 1) ? tqAddQual(tfu->imports,tfSyntaxFrAbSyn(stab
, ab)) : (tfu->imports)) : tqNewQualified(tfu->tf,tfSyntaxFrAbSyn
(stab, ab)))
;
2141 tfu->isExplicitImport = true1;
2142
2143 return tf;
2144}
2145
2146TForm
2147stabQualifiedInlineTForm(Stab stab, AbSyn ab, TForm tf)
2148{
2149 TFormUses tfu = tfuSetFlag(stab, tf, tformDoNothing);
2150
2151 tfuSetQualified(tfu->inlines, tfu->tf, tfSyntaxFrAbSyn(stab, ab))((tfu->inlines) = (tfu->inlines) ? (((tfu->inlines)->
isQual == 1) ? tqAddQual(tfu->inlines,tfSyntaxFrAbSyn(stab
, ab)) : (tfu->inlines)) : tqNewQualified(tfu->tf,tfSyntaxFrAbSyn
(stab, ab)))
;
2152
2153 return tf;
2154}
2155
2156/*
2157 * Add an id declared to be an extension with the type tf.
2158 */
2159TForm
2160stabAddTFormExtension(Stab stab, TForm tf, AbSyn extension)
2161{
2162 TFormUses tfu;
2163 int i, declc = 0;
2164 AbSyn *declv;
2165
2166 tfu = tfuSetFlag(stab, tf, tformDoNothing);
2167
2168 switch (abTag(extension)((extension)->abHdr.tag)) {
2169 case AB_Nothing:
2170 declc = 0;
2171 declv = 0;
2172 break;
2173 case AB_Sequence:
2174 case AB_Comma:
2175 declc = abArgc(extension)((extension)->abHdr.argc);
2176 declv = abArgv(extension)((extension)->abGen.data.argv);
2177 break;
2178 default:
2179 declc = 1;
2180 declv = &extension;
2181 break;
2182 }
2183
2184 for (i = 0; i < declc; i += 1)
2185 tfu->extension = listCons(AbSyn)(AbSyn_listPointer->Cons)(declv[i], tfu->extension);
2186
2187 return tf;
2188}
2189
2190/*
2191 * Add an id declared to be an extendee with the type tf.
2192 */
2193TForm
2194stabAddTFormExtendees(Stab stab, TForm tf, AbSyn extendees)
2195{
2196 TFormUses tfu;
2197 int i, declc = 0;
2198 AbSyn *declv;
2199
2200 tfu = tfuSetFlag(stab, tf, tformDoNothing);
2201
2202 switch (abTag(extendees)((extendees)->abHdr.tag)) {
2203 case AB_Nothing:
2204 declc = 0;
2205 declv = 0;
2206 break;
2207 case AB_Sequence:
2208 case AB_Comma:
2209 declc = abArgc(extendees)((extendees)->abHdr.argc);
2210 declv = abArgv(extendees)((extendees)->abGen.data.argv);
2211 break;
2212 default:
2213 declc = 1;
2214 declv = &extendees;
2215 break;
2216 }
2217
2218 for (i = 0; i < declc; i += 1)
2219 tfu->extendees = listCons(AbSyn)(AbSyn_listPointer->Cons)(declv[i], tfu->extendees);
2220
2221 return tf;
2222}
2223
2224/*
2225 * Record the fact that the question "dom has cat" has been asked.
2226 */
2227TForm
2228stabAddTFormQuery(Stab stab, TForm dom, TForm cat)
2229{
2230 tfFollow(dom)((dom) = tfFollowFn(dom));
2231 tfAddQuery(dom, cat);
2232 if (tfIsSyntax(dom)(((dom)->tag) == TF_Syntax) && abIsTheId(tfGetExpr(dom), ssymSelf)(((((dom)->__absyn))->abHdr.tag == (AB_Id)) && (
(((dom)->__absyn))->abId.sym)==(ssymSelf))
) {
2233 TFormUses tfu = stabFindTFormUses(stab, tfExpr(cat)tfToAbSyn(cat));
2234 tformCatConditionImport(tfu);
2235 }
2236 return dom;
2237}
2238
2239/*
2240 * Add an id declared to have type tf if not already in the list.
2241 * Handles sequences or commas of ids.
2242 */
2243TForm
2244stabAddTFormDeclaree(Stab stab, TForm tf, AbSyn declarees)
2245{
2246 TFormUses tfu;
2247 int i, declc = 0;
2248 AbSyn *declv;
2249 Bool wasEmpty;
2250
2251 tfu = tfuSetFlag(stab, tf, tformDoNothing);
2252
2253 switch (abTag(declarees)((declarees)->abHdr.tag)) {
2254 case AB_Nothing:
2255 declc = 0;
2256 declv = 0;
2257 break;
2258 case AB_Sequence:
2259 case AB_Comma:
2260 declc = abArgc(declarees)((declarees)->abHdr.argc);
2261 declv = abArgv(declarees)((declarees)->abGen.data.argv);
2262 break;
2263 default:
2264 declc = 1;
2265 declv = &declarees;
2266 break;
2267 }
2268
2269 wasEmpty = tfu->declarees ? false((int) 0) : true1;
2270
2271 for (i = 0; i < declc; i += 1) {
2272 Symbol s = declv[i]->abId.sym;
2273 if (wasEmpty || ! listMemq(Symbol)(Symbol_listPointer->Memq)(tfu->declarees, s))
2274 tfu->declarees = listCons(Symbol)(Symbol_listPointer->Cons)(s, tfu->declarees);
2275 }
2276
2277 return tfu->tf;
2278}
2279
2280
2281TForm
2282stabGetTForm(Stab stab, AbSyn ab, TForm failed)
2283{
2284 TFormUses tfu;
2285 TForm tf;
2286
2287 assert(stab != 0)do { if (!(stab != 0)) _do_assert(("stab != 0"),"stab.c",2287
); } while (0)
;
2288
2289 if (stabLevelIsLocked(stab)(((stab)->first)->isLocked))
2290 return stabGetTForm(cdr(stab)((stab)->rest), ab, failed);
2291
2292 tf = findTFormUnused(stab, ab);
2293 if (tf)
2294 return tf;
2295
2296 tfu = stabFindTFormUses(stab, ab);
2297 if (tfu)
2298 return tfu->tf;
2299
2300 return failed;
2301}
2302
2303TForm
2304stabDefTForm(Stab stab, TForm tf)
2305{
2306 /* !! presume NOT already present */
2307 /* !! (this is presumptious) */
2308 if (stabLevelIsLocked(stab)(((stab)->first)->isLocked))
2309 stabDefTForm(cdr(stab)((stab)->rest), tf);
2310
2311#if 0
2312 /* Someone turn this into a proper -Wd debug hook ... */
2313 if (tfGetExpr(tf)((tf)->__absyn) && abIsTheId(tfGetExpr(tf), ssymSelf)(((((tf)->__absyn))->abHdr.tag == (AB_Id)) && (
(((tf)->__absyn))->abId.sym)==(ssymSelf))
)
2314 {
2315 Stab fil = stabFile();
2316 SrcPosStack sposStk = tfGetExpr(tf)((tf)->__absyn)->abHdr.pos;
2317
2318 (void)fprintf(dbOut, "defTForm: <%3d: %d/%d> (%3d: %d/%d)\n",
2319 stabSerialNo(stab)(((stab)->first)->serialNo),
2320 stabLevelNo(stab)(((stab)->first)->lexicalLevel),
2321 stabLambdaLevelNo(stab)(((stab)->first)->lambdaLevel),
2322 stabSerialNo(fil)(((fil)->first)->serialNo),
2323 stabLevelNo(fil)(((fil)->first)->lexicalLevel),
2324 stabLambdaLevelNo(fil)(((fil)->first)->lambdaLevel));
2325 if (sposStk.stack != NULL((void*)0))
2326 {
2327 SrcPos pos = spstackFirst(sposStk);
2328 spstackPrintLine(dbOut, pos);
2329 }
2330 fnewline(dbOut);
2331 }
2332#endif
2333
2334 return addTFormUnused(stab, tf);
2335}
2336
2337Bool
2338stabIsImportedTForm(Stab stab, TForm tf)
2339{
2340 /*
2341 * This function walks up the stab stack to see if tf has already been
2342 * imported.
2343 */
2344
2345 /* Sanity check/hack */
2346 if (!tfHasSelf(tf)((tf)->hasSelf))
2347 {
2348 /*
2349 * Something bad has happened to the tf but we re-import
2350 * it anyway. See tfCopyQueries for one example of "Bad".
2351 * Currently, we don't reset it anywhere else.
2352 */
2353 /* (void)fprintf(dbOut, "(((ooops)))\n"); */
2354 return false((int) 0);
2355 }
2356
2357 for (; stab; stab = cdr(stab)((stab)->rest)) {
2358 TFormUses tfu = stabFindTFormUses(stab, tfExpr(tf)tfToAbSyn(tf));
2359
2360 if (tfu && tfu->isImported) {
2361 if (tfIsMeaning(tfu->tf)(((tfu->tf)->state)>=TF_State_Meaning) && tfIsMeaning(tf)(((tf)->state)>=TF_State_Meaning) &&
2362 !tformEqual(tfu->tf, tf))
2363 continue;
2364 return true1;
2365 }
2366 }
2367 return false((int) 0);
2368}
2369
2370TForm
2371stabFindOuterTForm(Stab stab, AbSyn ab)
2372{
2373 assert(stab)do { if (!(stab)) _do_assert(("stab"),"stab.c",2373); } while
(0)
;
2374
2375 for (; stab; stab = cdr(stab)((stab)->rest)) {
2376 TForm tf = findTFormUnused(stab, ab);
2377
2378 if (! tf) {
2379 TFormUses tfu = stabFindTFormUses(stab, ab);
2380 if (tfu)
2381 tf = tfu->tf;
2382 }
2383 if (tf) {
2384 tfFollow(tf)((tf) = tfFollowFn(tf));
2385 return tf;
2386 }
2387 }
2388 return NULL((void*)0);
2389}
2390
2391
2392/*
2393 * getAllTypesUsed recurses from sl down and gets all types imported,
2394 * inlined, or otherwise used. The first two list may overlap but the
2395 * third will not overlap either of the other two.
2396 */
2397
2398localstatic void getAllTypesUsed0(StabLevel sl, struct typesUsed *tu);
2399
2400struct typesUsed *
2401getAllTypesUsed(StabLevel sl)
2402{
2403 struct typesUsed *tu = (struct typesUsed *)
2404 stoAlloc((unsigned) OB_Other0, sizeof(struct typesUsed));
2405
2406 tu->typesImported = tu->typesInlined = tu->typesOther = 0;
2407
2408 getAllTypesUsed0(sl, tu);
2409
2410 /*
2411 * do a final check to make sure 'other' types are not imported
2412 * or inlined.
2413 */
2414
2415 if (tu->typesOther) {
2416 AbSynList al = tu->typesOther, reallyUnused = 0;
2417
2418 while (al) {
2419 int pos;
2420 AbSyn ab = car(al)((al)->first);
2421
2422 al = cdr(al)((al)->rest);
2423 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesImported,ab,abEqual,&pos);
2424 if (pos != -1)
2425 continue;
2426 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesInlined,ab,abEqual,&pos);
2427 if (pos == -1)
2428 reallyUnused = listCons(AbSyn)(AbSyn_listPointer->Cons)(ab,reallyUnused);
2429 }
2430
2431 if (reallyUnused) {
2432 listFree(AbSyn)(AbSyn_listPointer->Free)(tu->typesOther);
2433 tu->typesOther = reallyUnused;
2434 }
2435 }
2436
2437
2438 return tu;
2439}
2440
2441localstatic void
2442getAllTypesUsed0(StabLevel sl, struct typesUsed *tu)
2443{
2444 StabList children = sl->children;
2445 TFormUsesList tfuses = sl->tformsUsed.list;
2446 TFormList tfunused = sl->tformsUnused;
2447
2448 /* first do children and then me */
2449
2450 while (children) {
2451 getAllTypesUsed0(car(car(children))((((children)->first))->first), tu);
2452 children = cdr(children)((children)->rest);
2453 }
2454
2455 /* iterate across the used tforms */
2456
2457 while (tfuses) {
2458 Bool used = false((int) 0);
2459 TFormUses tfu = car(tfuses)((tfuses)->first);
2460 AbSyn ab;
2461 int pos;
2462
2463 tfuses = cdr(tfuses)((tfuses)->rest);
2464 if (tfIsWith(tfu->tf)(((tfu->tf)->tag) == TF_With))
2465 continue;
2466 ab = tfGetExpr(tfu->tf)((tfu->tf)->__absyn);
2467 if (abHasTag(ab, AB_Apply)((ab)->abHdr.tag == (AB_Apply)))
2468 ab = ab->abApply.op;
2469 if (abHasTag(ab, AB_With)((ab)->abHdr.tag == (AB_With)))
2470 continue;
2471
2472 if (tfu->imports) {
2473 used = true1;
2474 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesImported,ab,abEqual,&pos);
2475 if (pos == -1)
2476 tu->typesImported =
2477 listCons(AbSyn)(AbSyn_listPointer->Cons)(ab,tu->typesImported);
2478 }
2479
2480 if (tfu->inlines) {
2481 used = true1;
2482 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesInlined,ab,abEqual,&pos);
2483 if (pos == -1)
2484 tu->typesInlined =
2485 listCons(AbSyn)(AbSyn_listPointer->Cons)(ab,tu->typesInlined);
2486 }
2487
2488 if (used == false((int) 0)) {
2489 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesOther,ab,abEqual,&pos);
2490 if (pos == -1)
2491 tu->typesOther =
2492 listCons(AbSyn)(AbSyn_listPointer->Cons)(ab,tu->typesOther);
2493 }
2494 }
2495
2496 /* iterate across the unused tforms */
2497
2498 while (tfunused) {
2499 TForm tf = car(tfunused)((tfunused)->first);
2500 AbSyn ab;
2501 int pos;
2502
2503 tfunused = cdr(tfunused)((tfunused)->rest);
2504
2505 if (tfIsWith(tf)(((tf)->tag) == TF_With))
2506 continue;
2507 ab = tfGetExpr(tf)((tf)->__absyn);
2508 if (abHasTag(ab, AB_Apply)((ab)->abHdr.tag == (AB_Apply)))
2509 ab = ab->abApply.op;
2510 if (abHasTag(ab, AB_With)((ab)->abHdr.tag == (AB_With)))
2511 continue;
2512
2513 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesImported,ab,abEqual,&pos);
2514 if (pos != -1)
2515 continue;
2516
2517 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesInlined,ab,abEqual,&pos);
2518 if (pos != -1)
2519 continue;
2520
2521 listFind(AbSyn)(AbSyn_listPointer->Find)(tu->typesOther,ab,abEqual,&pos);
2522 if (pos == -1)
2523 tu->typesOther = listCons(AbSyn)(AbSyn_listPointer->Cons)(ab,tu->typesOther);
2524 }
2525}
2526
2527
2528/*
2529 * stabAddLabel(stab, label): Add label to the list of labels in this scope.
2530 * It is an error if the label is already present.
2531 */
2532void
2533stabAddLabel(Stab stab, AbSyn label)
2534{
2535 Symbol labsym = label->abId.sym;
2536 if (stabLabelExistsInThisStab(stab, labsym)) {
2537 AbSyn abLab = stabGetLabelInThisStab(stab, labsym);
2538 comsgNError(label, ALDOR_E_StabDupLabels139, symString(labsym)((labsym)->str));
2539 comsgNote(abLab, ALDOR_N_Here3);
2540 }
2541 else {
2542 Syme syme = symeNewLabel(labsym, tfNone()tfMulti(0), car(stab)((stab)->first));
2543 abSetSyme(label, syme);
2544 car(stab)((stab)->first)->labelsInScope =
2545 listCons(AbSyn)(AbSyn_listPointer->Cons)(label, car(stab)((stab)->first)->labelsInScope);
2546 }
2547}
2548
2549/*
2550 * stabGetAllLabels(stab): return a list of all labels in this or outer scopes.
2551 */
2552AbSynList
2553stabGetAllLabels(Stab stab)
2554{
2555 Stab stab0;
2556 AbSynList allLabels = listNil(AbSyn)((AbSynList) 0);
2557 for (stab0 = stab; stab0; stab0 = cdr(stab0)((stab0)->rest))
2558 allLabels = listConcat(AbSyn)(AbSyn_listPointer->Concat)(car(stab)((stab)->first)->labelsInScope,
2559 allLabels);
2560 return allLabels;
2561}
2562
2563/*
2564 * stabLabelExists(stab, label): returns true if the label is present in
2565 * this or any outer scope, false otherwise.
2566 */
2567Bool
2568stabLabelExists(Stab stab, Symbol label)
2569{
2570 Stab stab0;
2571 for (stab0 = stab; stab0; stab0 = cdr(stab0)((stab0)->rest))
2572 if (stabLabelExistsInThisStab(stab0, label))
2573 return true1;
2574 return false((int) 0);
2575}
2576
2577/*
2578 * stabLabelExistsInThisStab(stab, label): returns true if the label is
2579 * present in this symbol table level, false otherwise.
2580 */
2581Bool
2582stabLabelExistsInThisStab(Stab stab, Symbol label)
2583{
2584 AbSynList asl = car(stab)((stab)->first)->labelsInScope;
2585 while (asl) {
2586 if (label == car(asl)((asl)->first)->abId.sym)
2587 return true1;
2588 asl = cdr(asl)((asl)->rest);
2589 }
2590 return false((int) 0);
2591}
2592
2593/*
2594 * stabGetLabels(stab, label): returns all labels (absyns) with the given
2595 * name in this or any outer symbol table level.
2596 */
2597AbSynList
2598stabGetLabels(Stab stab, Symbol label)
2599{
2600 AbSynList labels = listNil(AbSyn)((AbSynList) 0);
2601 Stab stab0;
2602
2603 for (stab0 = stab; stab0; stab0 = cdr(stab0)((stab0)->rest)) {
2604 AbSyn foundLabel = stabGetLabelInThisStab(stab0, label);
2605 if (foundLabel)
2606 labels = listCons(AbSyn)(AbSyn_listPointer->Cons)(foundLabel, labels);
2607 }
2608 return listNReverse(AbSyn)(AbSyn_listPointer->NReverse)(labels);
2609}
2610
2611/*
2612 * stabGetLabelInThisStab(stab, label): returns the unique label in this
2613 * symbol table level with the given name, if it exists. If it is
2614 * note present, 0 is returned.
2615 */
2616AbSyn
2617stabGetLabelInThisStab(Stab stab, Symbol label)
2618{
2619 AbSynList asl = car(stab)((stab)->first)->labelsInScope;
2620 while (asl) {
2621 if (label == car(asl)((asl)->first)->abId.sym)
2622 return car(asl)((asl)->first);
2623 asl = cdr(asl)((asl)->rest);
2624 }
2625 return 0;
2626}
2627
2628/* If an inner stab level can be found which binds syme, return it. */
2629Stab
2630stabFindLevel(Stab stab, Syme syme)
2631{
2632 StabList sl;
2633
2634 if (stabLevelNo(stab)(((stab)->first)->lexicalLevel) >= symeDefLevelNo(syme)(symeDefLevel(syme)->lexicalLevel))
2635 return stab;
2636
2637 for (sl = car(stab)((stab)->first)->children; sl; sl = cdr(sl)((sl)->rest)) {
2638 Stab istab = car(sl)((sl)->first), nstab;
2639
2640 if (car(istab)((istab)->first) == symeDefLevel(syme))
2641 return istab;
2642
2643 nstab = stabFindLevel(istab, syme);
2644 if (nstab != istab)
2645 return nstab;
2646 }
2647
2648 return stab;
2649}
2650
2651
2652Bool stabIsChild(Stab parent, Stab child)
2653{
2654 Bool isChild = false((int) 0);
2655
2656 while (child != listNil(StabLevel)((StabLevelList) 0)) {
2657 if (child == parent)
2658 return true1;
2659 child = cdr(child)((child)->rest);
2660 }
2661
2662 return isChild;
2663}