Bug Summary

File:src/stab.c
Warning:line 383, column 9
Access to field 'argc' results in a dereference of a null pointer (loaded from variable 'stent')

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))
) {
62
Assuming field 'kind' is not equal to SYME_Trigger
63
'?' condition is false
64
Assuming the condition is true
65
'?' condition is true
66
Assuming the condition is false
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)) {
67
Taking false branch
68
'?' condition is false
69
'?' condition is true
70
Assuming the condition is false
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))
) {
71
'?' condition is false
72
Assuming the condition is false
73
Taking false branch
361 stabEntryPutSyme(stent, int0((int) 0), syme);
362 if (!stabEntryIsGeneric(stent))
363 stabEntryPutSyme(stent, 1, syme);
364 }
365 else if (symeCondition(syme)) {
74
Assuming the condition is true
75
Taking true branch
366 if (stabEntryIsGeneric(stent)) {
76
Passing null pointer value via 1st parameter 'stent'
77
Calling 'stabEntryIsGeneric'
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;
78
Access to field 'argc' results in a dereference of a null pointer (loaded from variable 'stent')
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));
36
Assuming 'stabDebug' is 0
37
Taking true branch
636
637 stab = stab0;
638 stent = 0;
639 while (stab
37.1
'stab' is non-null
&& !stent) {
38
Loop condition is true. Entering loop body
640 stabDEBUGif (!stabDebug) { } else afprintf(dbOut,
39
Taking true branch
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
39.1
'recurse' is 0
)
40
Taking true branch
646 break;
647 if (! stent)
648 stab = cdr(stab)((stab)->rest);
649 }
650
651 if (!stent) {
41
Execution continues on line 651
42
Assuming 'stent' is null
43
Taking true branch
652 stent = stabEntryNew();
44
Value assigned to 'stent'
653 tblSetElt(car(stab0)((stab0)->first)->tbl, id, stent);
654 stabDEBUGif (!stabDebug) { } else afprintf(dbOut, " ... manufacturing");
45
Assuming 'stabDebug' is 0
46
Taking true branch
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) {
47
Taking false branch
664 fnewline(dbOut);
665 }
666 stabEntryGetTypes(stent, ablogFalse());
667
668 if (DEBUG(stab)stabDebug) {
48
Assuming 'stabDebug' is 0
49
Taking false branch
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;
50
Returning pointer (loaded from 'stent'), which participates in a condition later
51
Returning pointer (loaded from '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
23.1
'result' is 0
&& stab; stab = cdr(stab)((stab)->rest)) {
24
Loop condition is true. Entering loop body
28
Assuming 'result' is 0
29
Loop condition is false. Execution continues on line 1176
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);
25
Assuming 'stent' is null
26
'?' condition is false
1173 result = listMemq(Syme)(Syme_listPointer->Memq)(symes, syme);
27
Value assigned to field 'kind', which participates in a condition later
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)
;
12
Assuming 'stab' is not equal to null
13
Taking false branch
14
Loop condition is false. Exiting loop
18
Assuming 'stab' is not equal to null
19
Taking false branch
20
Loop condition is false. Exiting loop
1186
1187 if (stabLevelIsLocked(stab)(((stab)->first)->isLocked))
15
Assuming field 'isLocked' is not equal to 0
16
Taking true branch
21
Assuming field 'isLocked' is 0
22
Taking false branch
1188 return stabAddMeaning(cdr(stab)((stab)->rest), syme);
17
Calling 'stabAddMeaning'
1189
1190 if (stabHasMeaning(stab, syme))
23
Calling 'stabHasMeaning'
30
Returning from 'stabHasMeaning'
31
Taking false branch
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)
) {
32
Assuming field 'kind' is not equal to SYME_Trigger
33
'?' condition is false
34
Control jumps to 'case SYME_LexVar:' at line 1196
1196 case SYME_LexVar:
1197 case SYME_Param:
1198 case SYME_Extend:
1199 stent = stabGetEntry(stab, id, false((int) 0));
35
Calling 'stabGetEntry'
52
Returning from 'stabGetEntry'
53
Value assigned to 'stent'
1200 break;
54
Execution continues on line 1206
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))
)
55
'?' condition is false
1207 symeRefreshExtendees(syme);
1208
1209 if (stent) {
56
Assuming 'stent' is null
57
Taking false branch
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,
58
Assuming 'stabDebug' is 0
59
Taking true branch
1231 syme, symeCondition(syme));
1232 stabEntryAddSyme(stent, syme);
60
Passing null pointer value via 1st parameter 'stent'
61
Calling 'stabEntryAddSyme'
1233
1234 return syme;
1235}
1236
1237void
1238stabPutMeaningSet(Stab stab, SymeSet symeSet)
1239{
1240 stabPutMeanings(stab, symeSetList(symeSet));
9
Calling 'stabPutMeanings'
1241}
1242
1243void
1244stabPutMeanings(Stab stab, SymeList symes)
1245{
1246 SymeList l;
1247
1248 for (l = symes; l; l = cdr(l)((l)->rest)) {
10
Loop condition is true. Entering loop body
1249 Syme syme = car(l)((l)->first);
1250
1251 stabAddMeaning(stab, syme);
11
Calling 'stabAddMeaning'
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);
1472 SymeList symes;
1473
1474 for (symes = stabGetMeanings(stab, NULL((void*)0), sym); symes; symes = cdr(symes)((symes)->rest))
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)
;
1479 symeSetType(syme, tform);
1480 stabPropagateDecl(stab, syme);
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);
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())
1
Assuming the condition is false
2
Taking false branch
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))
3
Taking false branch
1749 return listNil(TQual)((TQualList) 0);
1750
1751 if (DEBUG(stabImport)stabImportDebug) {
4
Assuming 'stabImportDebug' is 0
5
Taking false branch
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))
6
Assuming field 'status' is equal to TQUAL_Foreign
7
Taking true branch
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);
8
Calling 'stabPutMeaningSet'
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}