1 /* table.c - table handler for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
5 /* Can I now get rid of EXPRLEVEL? Yes, except expression symbols must
6 * usually be set to some level different from OFFKLUDGELEVEL.
24 #define GOLDEN 157 /* GOLDEN/HASHTABSIZE approx golden ratio */
25 #define HASHTABSIZE 256
26 #define MARKER ((unsigned) 0x18C396A5L) /* lint everywhere it is used */
27 #ifdef VERY_SMALL_MEMORY
39 #define STACKSPACE 256 /* punt for normal recursions - switch extra */
63 struct typestruct
**tdtypeptr
;
66 PRIVATE
struct symstruct exprsyms
[MAXEXPR
];
67 PRIVATE
struct symstruct
*hashtab
[HASHTABSIZE
];
68 /* depends on zero init */
70 PRIVATE
struct string
*laststring
; /* last in list of strings */
71 /* depends on NULL init */
73 PUBLIC
struct symstruct locsyms
[MAXLOCAL
];
75 PRIVATE
struct symstruct constemplate
=
77 CONSTANT
, /* storage */
80 EXPRLEVEL
, /* level */
83 NULL
, /* type, init later to itype */
84 /* offset is a union, set every time constemplate is used */
85 /* name is a union, namea member is constant "\0" */
88 PRIVATE
struct keywordstruct keywords
[NKEYWORDS
] =
90 { "enum", ENUMDECL
, },
91 { "struct", STRUCTDECL
, },
92 { "union", UNIONDECL
, },
93 { "unsigned", UNSIGNDECL
, },
94 { "signed", SIGNDECL
, },
96 { "auto", AUTODECL
, },
97 { "extern", EXTERNDECL
, },
98 { "register", REGDECL
, },
99 { "static", STATICDECL
, },
101 { "typedef", TYPEDEFDECL
, },
104 { "break", BREAKSYM
, },
105 { "case", CASESYM
, },
106 { "continue", CONTSYM
, },
107 { "default", DEFAULTSYM
, },
109 { "else", ELSESYM
, },
111 { "goto", GOTOSYM
, },
113 { "return", RETURNSYM
, },
114 { "sizeof", SIZEOFSYM
, },
115 { "switch", SWITCHSYM
, },
116 { "while", WHILESYM
, },
118 { "#asm", ASMCNTL
, },
119 { "#define", DEFINECNTL
, },
120 { "#elif", ELIFCNTL
, },
121 { "#else", ELSECNTL
, },
122 { "#endasm", ENDASMCNTL
, },
123 { "#endif", ENDIFCNTL
, },
125 { "#ifdef", IFDEFCNTL
, },
126 { "#include", INCLUDECNTL
, },
127 { "#ifndef", IFNDEFCNTL
, },
128 { "#line", LINECNTL
, },
129 { "#undef", UNDEFCNTL
, },
130 { "#warning", WARNINGCNTL
, },
131 { "#error", ERRORCNTL
, },
133 { "defined", DEFINEDSYM
, }, /* should be deactivated except in #if's */
136 PRIVATE
struct typedatastruct scaltypes
[NSCALTYPES
] =
138 { "void", TRUE
, 0, 0, &vtype
, }, /* first - addkeyword uses vtype */
139 { "char", TRUE
, CHAR
, 1, &ctype
, },
140 { "char", FALSE
, UNSIGNED
| CHAR
, 1, &uctype
, },
141 { "char", FALSE
, CHAR
, 1, &sctype
, },
142 { "short", TRUE
, SHORT
, 2, &stype
, },
143 { "short", FALSE
, UNSIGNED
| SHORT
, 2, &ustype
, },
144 { "int", TRUE
, INT
, 2, &itype
, },
145 { "int", FALSE
, UNSIGNED
| INT
, 2, &uitype
, },
146 { "long", TRUE
, LONG
| DLONG
, 4, <ype
, },
147 { "long", FALSE
, UNSIGNED
| LONG
| DLONG
, 4, &ultype
, },
149 { "float", TRUE
, FLOAT
, 4, &fltype
, },
150 { "double", TRUE
, DOUBLE
, 8, &dtype
, },
154 FORWARD
struct symstruct
*addkeyword
P((char *name
, sym_pt code
));
155 FORWARD
void heapcorrupterror
P((void));
157 PUBLIC
struct symstruct
*addglb(name
, type
)
159 struct typestruct
*type
;
161 struct symstruct
**hashptr
;
162 struct symstruct
*oldsymptr
= NULL
; /* for -Wall */
163 register struct symstruct
*symptr
;
165 hashptr
= gethashptr(name
);
167 while (symptr
!= NULL
)
170 symptr
= symptr
->next
;
172 symptr
= qmalloc(sizeof (struct symstruct
) + strlen(name
));
175 ts_size_global
+= sizeof (struct symstruct
) + strlen(name
);
177 addsym(name
, type
, symptr
);
178 symptr
->storage
= GLOBAL
;
179 symptr
->level
= GLBLEVEL
;
180 if (*hashptr
== NULL
)
183 symptr
->prev
= hashptr
;
187 oldsymptr
->next
= symptr
;
188 symptr
->prev
= &oldsymptr
->next
;
193 PRIVATE
struct symstruct
*addkeyword(name
, code
)
197 struct symstruct
*symptr
;
199 (symptr
= addglb(name
, vtype
))->flags
= KEYWORD
;
200 symptr
->offset
.offsym
= code
;
204 PUBLIC
struct symstruct
*addloc(name
, type
)
206 struct typestruct
*type
;
208 struct symstruct
**hashptr
;
209 register struct symstruct
*symptr
;
211 hashptr
= gethashptr(name
);
213 while (symptr
!= NULL
)
214 symptr
= symptr
->next
;
216 locptr
= (struct symstruct
*) align(&symptr
->name
.namea
[strlen(name
) + 1]);
217 if (locptr
>= &locsyms
[MAXLOCAL
])
218 limiterror("too many local symbols (101)");
219 addsym(name
, type
, symptr
);
220 if (type
->constructor
== FUNCTION
)
221 symptr
->storage
= GLOBAL
;
223 symptr
->storage
= LOCAL
;
224 symptr
->level
= level
;
225 if (*hashptr
!= NULL
)
227 symptr
->next
= *hashptr
;
228 symptr
->next
->prev
= &symptr
->next
;
231 symptr
->prev
= hashptr
;
235 PUBLIC
struct symstruct
*addlorg(name
, type
)
237 struct typestruct
*type
;
239 if (level
!= GLBLEVEL
)
240 return addloc(name
, type
);
241 return addglb(name
, type
);
244 PUBLIC
void addsym(name
, type
, symptr
)
246 struct typestruct
*type
;
247 register struct symstruct
*symptr
;
249 if (type
->constructor
& (ARRAY
| FUNCTION
))
250 symptr
->indcount
= 0;
252 symptr
->indcount
= 1;
256 symptr
->offset
.offi
= 0;
257 strcpy(symptr
->name
.namea
, name
);
260 PUBLIC
struct symstruct
*constsym(longconst
)
263 register struct symstruct
*symptr
;
265 symptr
= exprsym(&constemplate
);
266 symptr
->offset
.offv
= longconst
;
270 PUBLIC
void delsym(symptr
)
271 register struct symstruct
*symptr
;
273 if ((*(symptr
->prev
) = symptr
->next
) != NULL
)
274 symptr
->next
->prev
= symptr
->prev
;
277 /* dumpglbs() - define locations of globals and reserve space for them */
279 PUBLIC
void dumpglbs()
282 register struct symstruct
*symptr
;
283 register struct typestruct
*type
;
286 extern char *brksize
;
292 static struct ts ts
[] =
294 "ts_n_newtypelist ", &ts_n_newtypelist
,
295 "ts_s_newtypelist ", &ts_s_newtypelist
,
296 "ts_n_filename_term ", &ts_n_filename_term
,
297 "ts_s_filename_term ", &ts_s_filename_term
,
298 "ts_n_filename ", &ts_n_filename
,
299 "ts_s_filename ", &ts_s_filename
,
300 "ts_s_filename_tot ", &ts_s_filename_tot
,
301 "ts_n_pathname ", &ts_n_pathname
,
302 "ts_s_pathname ", &ts_s_pathname
,
303 "ts_s_pathname_tot ", &ts_s_pathname_tot
,
304 "ts_n_inputbuf ", &ts_n_inputbuf
,
305 "ts_s_inputbuf ", &ts_s_inputbuf
,
306 "ts_s_inputbuf_tot ", &ts_s_inputbuf_tot
,
307 "ts_n_includelist ", &ts_n_includelist
,
308 "ts_s_includelist ", &ts_s_includelist
,
309 "ts_s_outputbuf ", &ts_s_outputbuf
,
310 "ts_n_macstring_ident ", &ts_n_macstring_ident
,
311 "ts_n_macstring_ordinary ", &ts_n_macstring_ordinary
,
312 "ts_n_macstring_param ", &ts_n_macstring_param
,
313 "ts_n_macstring_quoted ", &ts_n_macstring_quoted
,
314 "ts_n_macstring_term ", &ts_n_macstring_term
,
315 "ts_s_macstring ", &ts_s_macstring
,
316 "ts_n_defines ", &ts_n_defines
,
317 "ts_s_defines ", &ts_s_defines
,
318 "ts_n_macparam ", &ts_n_macparam
,
319 "ts_s_macparam ", &ts_s_macparam
,
320 "ts_s_macparam_tot ", &ts_s_macparam_tot
,
321 "ts_n_macparam_string_ordinary ", &ts_n_macparam_string_ordinary
,
322 "ts_n_macparam_string_quoted ", &ts_n_macparam_string_quoted
,
323 "ts_n_macparam_string_term ", &ts_n_macparam_string_term
,
324 "ts_s_macparam_string ", &ts_s_macparam_string
,
325 "ts_s_macparam_string_tot ", &ts_s_macparam_string_tot
,
326 "ts_s_macparam_string_alloced ", &ts_s_macparam_string_alloced
,
327 "ts_s_macparam_string_alloced_tot ", &ts_s_macparam_string_alloced_tot
,
328 "ts_s_fakeline ", &ts_s_fakeline
,
329 "ts_s_fakeline_tot ", &ts_s_fakeline_tot
,
330 "ts_n_string ", &ts_n_string
,
331 "ts_n_case ", &ts_n_case
,
332 "ts_n_case_realloc ", &ts_n_case_realloc
,
333 "ts_s_case ", &ts_s_case
,
334 "ts_s_case_tot ", &ts_s_case_tot
,
335 "ts_n_structname ", &ts_n_structname
,
336 "ts_s_structname ", &ts_s_structname
,
337 "ts_n_type ", &ts_n_type
,
338 "ts_s_type ", &ts_s_type
,
339 "ts_n_global ", &ts_n_global
,
340 "ts_size_global ", &ts_size_global
,
341 "ts_n_holdstr ", &ts_n_holdstr
,
342 "ts_size_holdstr ", &ts_size_holdstr
,
343 "ts_n_growobj ", &ts_n_growobj
,
344 "ts_size_growobj_wasted ", &ts_size_growobj_wasted
,
345 "ts_n_growheap ", &ts_n_growheap
,
346 "ts_s_growheap ", &ts_s_growheap
,
350 for (tp
= &ts
[0]; tp
< &ts
[sizeof ts
/ sizeof ts
[0]]; ++tp
)
355 outuvalue(*tp
->where
);
360 outhex((uvalue_t
) brksize
);
367 for (i
= 0; i
< HASHTABSIZE
; ++i
)
368 for (symptr
= hashtab
[i
]; symptr
!= NULL
; symptr
= symptr
->next
)
369 if (symptr
->storage
== GLOBAL
&& !(symptr
->flags
& EXTERNAL
)
370 && *symptr
->name
.namea
>= 'A' && symptr
->flags
<= MAXDUMPFLAG
371 /* Don't access type unless flags <= MAXDUMPFLAG, because
372 * type is punned to a symbol pointer for the label chain
375 && symptr
->type
->constructor
!= FUNCTION
)
378 if (symptr
->flags
& DIRECTPAGE
)
384 if (symptr
->flags
& STATIC
)
385 lcommon(symptr
->name
.namea
);
387 common(symptr
->name
.namea
);
388 outnhex(type
->typesize
);
396 /* dumplocs() - define offsets of current locals */
398 PUBLIC
void dumplocs()
400 register struct symstruct
*symptr
;
403 #ifdef ASM_USES_CALLEE_REGS
404 if (framep
&& optimise
&& !callersaves
) {
405 regfuse
|= callee1mask
;
406 outnstr("! Assuming #asm uses all callee saves registers");
410 for (i
= 0; i
< HASHTABSIZE
; ++i
)
411 for (symptr
= hashtab
[i
]; symptr
!= NULL
; symptr
= symptr
->next
)
412 if (symptr
->storage
== LOCAL
)
413 set(symptr
->name
.namea
, symptr
->offset
.offi
- sp
);
418 /* dumpstrings() - dump held-up strings */
420 PUBLIC
void dumpstrings()
422 struct string
*stringp
;
425 for (stringp
= laststring
; stringp
!= NULL
; stringp
= stringp
->snext
)
427 outnlabel(stringp
->slabel
);
428 defstr(stringp
->sptr
, stringp
->stop
, TRUE
);
429 dataoffset
+= stringp
->stop
- stringp
->sptr
+ 1;
435 PUBLIC
struct symstruct
*exprsym(symptr
)
436 struct symstruct
*symptr
;
438 register struct symstruct
*newsymptr
;
440 newsymptr
= exprptr
++;
441 if (exprptr
>= &exprsyms
[MAXEXPR
])
443 limiterror("expression too complex (501 symbols)");
445 limiterror("expression too complex (MAXEXPR)");
447 *newsymptr
= *symptr
;
448 newsymptr
->level
= EXPRLEVEL
;
449 newsymptr
->name
.namep
= symptr
->name
.namea
;
453 PUBLIC
struct symstruct
*findlorg(name
)
456 struct symstruct
*symptr
;
458 symptr
= *gethashptr(name
);
459 while (symptr
!= NULL
&& (strcmp(symptr
->name
.namea
, name
) != 0 ||
460 symptr
->flags
== STRUCTNAME
))
461 symptr
= symptr
->next
;
465 PUBLIC
struct symstruct
*findstruct(name
)
468 struct symstruct
*symptr
;
470 symptr
= *gethashptr(name
);
471 while (symptr
!= NULL
&& (symptr
->flags
!= STRUCTNAME
||
472 strcmp(symptr
->name
.namea
, name
) != 0))
473 symptr
= symptr
->next
;
477 /* convert name to a hash table ptr */
479 PUBLIC
struct symstruct
**gethashptr(sname
)
482 register int hashval
;
483 register char *rsname
;
489 hashval
= hashval
* 2 + *rsname
++;
493 hashval
= (rsname
[2] << 2) ^ rsname
[1] ^ (rsname
[0] << 1);
497 return hashtab
+ ((hashval
* GOLDEN
) & (HASHTABSIZE
- 1));
500 PRIVATE
void heapcorrupterror()
502 outofmemoryerror(" (heap corrupt - stack overflow?)");
507 /* hold string for dumping at end, to avoid mixing it with other data */
509 PUBLIC label_no
holdstr(sptr
, stop
)
513 register struct string
*stringp
;
515 stringp
= qmalloc(sizeof *stringp
);
518 ts_size_holdstr
+= sizeof *stringp
;
520 stringp
->snext
= laststring
;
521 stringp
->sptr
= sptr
;
522 stringp
->stop
= stop
;
523 laststring
= stringp
;
524 return stringp
->slabel
= getlabel();
527 #endif /* HOLDSTRINGS */
529 PUBLIC
void newlevel()
531 if (*(unsigned *) chartop
!= MARKER
)
533 if (level
>= MAXLEVEL
)
534 limiterror("compound statements nested too deeply (126 levels)");
539 PUBLIC
void oldlevel()
541 register struct symstruct
*symptr
;
543 if (*(unsigned *) chartop
!= MARKER
)
546 bugerror("not in a compound statement");
549 for (symptr
= &locsyms
[0]; symptr
< locptr
;
550 symptr
= (struct symstruct
*)
551 align(&symptr
->name
.namea
[strlen(symptr
->name
.namea
) + 1]))
552 if (symptr
->level
> level
)
556 PUBLIC
void ourfree(ptr
)
562 PUBLIC
void *ourmalloc(nbytes
)
567 if ((ptr
= malloc(nbytes
)) == NULL
)
568 outofmemoryerror("");
572 PUBLIC
void outofmemoryerror(message
)
575 error2error("compiler out of memory", message
);
582 for (size
= 0x1000; size
!= 0; --size
)
583 if ((ptr
= malloc(size
)) != NULL
)
585 outstr("found free memory at ");
586 outuvalue((uvalue_t
) ptr
);
588 outuvalue((uvalue_t
) size
);
597 PUBLIC
void *growobject(object
, extra
)
601 /* size_t */ unsigned oblength
;
603 /* It would be nice to realloc the previous memory if it can be left in
604 * the same place. Since a realloc that moves the memory can almost be
605 * relied on to mess up pointers before *obptr, and since malloc(extra)
606 * would be unlikely to produce memory adjoining chartop, it is not
607 * clear how to do this.
610 ts_size_growobj_wasted
+= chartop
- (char *) object
;
612 oblength
= (/* size_t */ unsigned) (charptr
- (char *) object
);
613 growheap(oblength
+ extra
);
617 memcpy(charptr
, object
, oblength
);
623 #define ALLOC_UNIT ((unsigned) 0x400)
625 #define ALLOC_OVERHEAD (S_ALIGNMENT - 1 + sizeof (unsigned))
627 #define ALLOC_OVERHEAD (sizeof (unsigned))
630 PUBLIC
void growheap(size
)
633 register char *newptr
;
635 if ((newptr
= malloc(size
+= ALLOC_UNIT
+ ALLOC_OVERHEAD
)) == NULL
636 && (newptr
= malloc(size
-= ALLOC_UNIT
)) == NULL
)
637 outofmemoryerror("");
640 ts_s_growheap
+= size
;
643 newptr
= (char *) align(newptr
+ size
- ALLOC_OVERHEAD
);
645 char1top
= newptr
- 1;
646 char3top
= newptr
- 3;
647 *(unsigned *) newptr
= MARKER
;
650 PUBLIC
void *qmalloc(size
)
655 if ((charptr
= (char *) align(charptr
)) + size
> chartop
)
662 PUBLIC
void swapsym(sym1
, sym2
)
663 struct symstruct
*sym1
;
664 struct symstruct
*sym2
;
666 struct symstruct swaptemp
;
673 PUBLIC
void syminit()
675 struct keywordstruct
*kwptr
;
676 struct typedatastruct
*tdptr
;
677 struct typestruct
*type
;
681 for (tdptr
= scaltypes
; tdptr
< scaltypes
+ NSCALTYPES
; ++tdptr
)
683 (*tdptr
->tdtypeptr
= type
= newtype())->scalar
= tdptr
->tdscalar
;
684 type
->alignmask
= ~((type
->typesize
= tdptr
->tdsize
) - 1) |
686 type
->tname
= tdptr
->tdname
;
687 if (tdptr
->tdkeyscalar
)
688 addkeyword(tdptr
->tdname
, TYPEDECL
)->type
= type
;
690 for (kwptr
= keywords
; kwptr
< keywords
+ NKEYWORDS
; ++kwptr
)
691 addkeyword(kwptr
->kwname
, kwptr
->kwcode
);
692 constemplate
.type
= itype
;