new copyright; att/bsd/shared
[unix-history] / usr / src / usr.bin / pascal / src / stab.c
CommitLineData
0fc6e47b
KB
1/*-
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
252367af 6 */
b721c131 7
b1148f06 8#ifndef lint
0fc6e47b
KB
9static char sccsid[] = "@(#)stab.c 5.4 (Berkeley) %G%";
10#endif /* not lint */
c6ae69c6
PK
11
12 /*
f67e1704 13 * Procedures to put out symbol table information
b721c131 14 * and stabs for separate compilation type checking.
f67e1704 15 * These use the .stabs, .stabn, and .stabd directives.
c6ae69c6
PK
16 */
17
c6ae69c6
PK
18#include "whoami.h"
19#ifdef PC
20 /* and the rest of the file */
21# include "0.h"
1ba5ecf2 22# include "objfmt.h"
73eeab33 23# include "yy.h"
c6ae69c6
PK
24# include <stab.h>
25
99f6998f
PK
26 /*
27 * additional symbol definition for <stab.h>
28 * that is used by the separate compilation facility --
29 * eventually, <stab.h> should be updated to include this
30 */
c6ae69c6 31
99f6998f 32# include "pstab.h"
c6ae69c6
PK
33# include "pc.h"
34
f67e1704
KM
35
36#define private static
37
38int oldway = 0;
39
b721c131
PK
40 /*
41 * absolute value: line numbers are negative if error recovery.
42 */
43#define ABS( x ) ( x < 0 ? -x : x )
3b091403 44long checksum();
b721c131 45
f67e1704
KM
46/*
47 * Generate information about variables.
48 */
49
50stabgvar (p, length, line)
51struct nl *p;
52int length, line;
53{
54 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x",
55 0, p->symbol, N_PC, N_PGVAR, ABS(line)
56 );
57 if (oldway != 0) {
58 oldstabgvar(p->symbol, p2type(p->type), 0, length, line);
59 } else if (opt('g')) {
60 putprintf("\t.stabs\t\"%s:G", 1, p->symbol);
61 gentype(p->type);
62 putprintf("\",0x%x,0,0x%x,0", 0, N_GSYM, length);
63 }
64}
65
66stablvar (p, offset, length)
67struct nl *p;
68int offset, length;
69{
70 int level;
71
72 level = (p->nl_block & 037);
73 if (oldway != 0) {
74 oldstablvar(p->symbol, p2type(p->type), level, offset, length);
75 } else if (opt('g')) {
76 putprintf("\t.stabs\t\"%s:", 1, p->symbol);
77 gentype(p->type);
78 putprintf("\",0x%x,0,0x%x,0x%x", 0, N_LSYM, length, offset);
79 }
80}
81
c6ae69c6 82 /*
c5e061f2 83 * global variables
c6ae69c6 84 */
b1148f06 85/*ARGSUSED*/
f67e1704 86oldstabgvar( name , type , offset , length , line )
c6ae69c6
PK
87 char *name;
88 int type;
c6ae69c6
PK
89 int offset;
90 int length;
b721c131 91 int line;
c6ae69c6 92 {
c6ae69c6
PK
93 if ( ! opt('g') ) {
94 return;
95 }
96 putprintf( " .stabs \"" , 1 );
b1148f06 97 putprintf( NAMEFORMAT , 1 , (int) name );
c5e061f2 98 putprintf( "\",0x%x,0,0x%x,0" , 0 , N_GSYM , type );
c6ae69c6 99 putprintf( " .stabs \"" , 1 );
b1148f06 100 putprintf( NAMEFORMAT , 1 , (int) name );
b721c131 101 putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
c5e061f2
PK
102}
103
104 /*
105 * local variables
106 */
b1148f06 107/*ARGSUSED*/
f67e1704 108oldstablvar( name , type , level , offset , length )
c5e061f2
PK
109 char *name;
110 int type;
111 int level;
112 int offset;
113 int length;
114 {
c6ae69c6 115
c5e061f2
PK
116 if ( ! opt('g') ) {
117 return;
118 }
119 putprintf( " .stabs \"" , 1 );
b1148f06 120 putprintf( NAMEFORMAT , 1 , (int) name );
c5e061f2
PK
121 putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_LSYM , type , -offset );
122 putprintf( " .stabs \"" , 1 );
b1148f06 123 putprintf( NAMEFORMAT , 1 , (int) name );
c5e061f2 124 putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
c6ae69c6
PK
125}
126
127
f67e1704
KM
128stabparam (p, offset, length)
129struct nl *p;
130int offset, length;
131{
132 if (oldway != 0) {
133 oldstabparam(p->symbol, p2type(p->type), offset, length);
134 } else if (opt('g')) {
135 putprintf("\t.stabs\t\"%s:", 1, p->symbol);
136 if (p->class == REF) {
137 putprintf("v", 1);
138 } else {
139 putprintf("p", 1);
140 }
141 gentype((p->class == FPROC || p->class ==FFUNC) ? p : p->type);
142 putprintf("\",0x%x,0,0x%x,0x%x", 0, N_PSYM, length, offset);
143 }
144}
145
c6ae69c6
PK
146 /*
147 * parameters
148 */
f67e1704 149oldstabparam( name , type , offset , length )
c6ae69c6
PK
150 char *name;
151 int type;
152 int offset;
153 int length;
154 {
155
156 if ( ! opt('g') ) {
157 return;
158 }
159 putprintf( " .stabs \"" , 1 );
b1148f06 160 putprintf( NAMEFORMAT , 1 , (int) name );
b721c131 161 putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_PSYM , type , offset );
c6ae69c6 162 putprintf( " .stabs \"" , 1 );
b1148f06 163 putprintf( NAMEFORMAT , 1 , (int) name );
b721c131 164 putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
c6ae69c6
PK
165 }
166
167 /*
168 * fields
169 */
c6ae69c6
PK
170
171 /*
172 * left brackets
f67e1704 173 * (dbx handles module-2 without these, so we won't use them either)
c6ae69c6
PK
174 */
175stablbrac( level )
176 int level;
177 {
178
f67e1704 179 if ( ! opt('g') || oldway == 0 ) {
c6ae69c6
PK
180 return;
181 }
b721c131 182 putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_LBRAC , level );
c6ae69c6
PK
183 }
184
185 /*
186 * right brackets
187 */
188stabrbrac( level )
189 int level;
190 {
191
f67e1704 192 if ( ! opt('g') || oldway == 0 ) {
c6ae69c6
PK
193 return;
194 }
b721c131 195 putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_RBRAC , level );
c6ae69c6
PK
196 }
197
f67e1704
KM
198stabfunc (p, name, line, level)
199struct nl *p;
200char *name;
201int line, level;
202{
203 char extname[BUFSIZ],nestspec[BUFSIZ];
204
205 if ( level == 1 ) {
206 if (p->class == FUNC) {
207 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x" ,
208 0 , name , N_PC , N_PGFUNC , ABS( line )
209 );
210 } else if (p->class == PROC) {
211 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x" ,
212 0 , name , N_PC , N_PGPROC , ABS( line )
213 );
214 }
215 }
216 if (oldway != 0) {
217 oldstabfunc(name, p->class, line, level);
218 } else if (opt('g')) {
219 putprintf("\t.stabs\t\"%s:", 1, name);
220 if (p->class == FUNC) {
221 putprintf("F", 1);
222 gentype(p->type);
223 putprintf(",", 1);
224 } else {
225 putprintf("P,", 1);
226 }
227 sextname(extname, name, level); /* set extname to entry label */
228 putprintf("%s,", 1, &(extname[1])); /* remove initial underbar */
229 snestspec(nestspec, level);
230 putprintf("%s\",0x%x,0,0,%s", 0, nestspec, N_FUN, extname);
231 }
232}
233
234 /*
235 * construct the colon-separated static nesting string into a
236 * caller-supplied buffer
237 */
238private snestspec(buffer, level)
239 char buffer[];
240 int level;
241{
242 char *starthere;
243 int i;
244
245 if (level <= 1) {
246 buffer[0] = '\0';
247 } else {
248 starthere = &buffer[0];
249 for ( i = 1 ; i < level ; i++ ) {
250 sprintf(starthere, "%s:", enclosing[i]);
251 starthere += strlen(enclosing[i]) + 1;
252 }
a7081ede 253 *--starthere = '\0'; /* remove last colon */
f67e1704
KM
254 if (starthere >= &buffer[BUFSIZ-1]) {
255 panic("snestspec");
256 }
257 }
258}
259
c6ae69c6
PK
260 /*
261 * functions
262 */
f67e1704 263oldstabfunc( name , typeclass , line , level )
c6ae69c6 264 char *name;
270467f1 265 int typeclass;
c6ae69c6
PK
266 int line;
267 long level;
268 {
078a6e08 269 char extname[ BUFSIZ ];
c6ae69c6 270
b721c131
PK
271 /*
272 * for sdb
273 */
c6ae69c6
PK
274 if ( ! opt('g') ) {
275 return;
276 }
277 putprintf( " .stabs \"" , 1 );
b1148f06
KM
278 putprintf( NAMEFORMAT , 1 , (int) name );
279 sextname( extname , name , (int) level );
280 putprintf( "\",0x%x,0,0x%x,%s" , 0 , N_FUN , line , (int) extname );
c6ae69c6
PK
281 }
282
283 /*
284 * source line numbers
285 */
286stabline( line )
287 int line;
288 {
289 if ( ! opt('g') ) {
290 return;
291 }
b721c131 292 putprintf( " .stabd 0x%x,0,0x%x" , 0 , N_SLINE , ABS( line ) );
c6ae69c6
PK
293 }
294
295 /*
f67e1704
KM
296 * source files get none or more of these:
297 * one as they are entered,
298 * and one every time they are returned to from nested #includes
c6ae69c6 299 */
f67e1704 300stabsource(filename, firsttime)
c6ae69c6 301 char *filename;
f67e1704 302 bool firsttime;
73eeab33
PK
303{
304 int label;
305
306 /*
307 * for separate compilation
308 */
309 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0,
24cec487 310 (int) filename, N_PC, N_PSO, N_FLAGCHECKSUM);
73eeab33 311 /*
f67e1704 312 * for debugger
73eeab33
PK
313 */
314 if ( ! opt('g') ) {
315 return;
c6ae69c6 316 }
f67e1704 317 if (oldway != 0) {
d71f4c92 318 label = (int) getlab();
f67e1704
KM
319 putprintf( " .stabs \"" , 1 );
320 putprintf( NAMEFORMAT , 1 , filename );
321 putprintf( "\",0x%x,0,0," , 1 , N_SO );
322 putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label );
323 putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label );
324 putprintf( ":" , 0 );
325 } else {
326 if (firsttime) {
327 putprintf( " .stabs \"" , 1 );
328 putprintf( NAMEFORMAT , 1 , filename );
329 putprintf( "\",0x%x,0,0,0" , 0 , N_SO );
330 }
331 }
73eeab33 332}
c6ae69c6
PK
333
334 /*
335 * included files get one or more of these:
336 * one as they are entered by a #include,
73eeab33 337 * and one every time they are returned to from nested #includes.
c6ae69c6 338 */
73eeab33 339stabinclude(filename, firsttime)
c6ae69c6 340 char *filename;
73eeab33
PK
341 bool firsttime;
342{
24cec487 343 int label;
73eeab33
PK
344 long check;
345
346 /*
347 * for separate compilation
348 */
349 if (firsttime) {
350 check = checksum(filename);
351 } else {
352 check = N_FLAGCHECKSUM;
c6ae69c6 353 }
73eeab33 354 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x", 0,
24cec487 355 (int) filename, N_PC, N_PSOL, check);
73eeab33
PK
356 /*
357 * for sdb
358 */
359 if ( ! opt('g') ) {
360 return;
361 }
f67e1704 362 if (oldway != 0) {
d71f4c92 363 label = (int) getlab();
f67e1704
KM
364 putprintf( " .stabs \"" , 1 );
365 putprintf( NAMEFORMAT , 1 , filename );
366 putprintf( "\",0x%x,0,0," , 1 , N_SOL );
367 putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label );
368 putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label );
369 putprintf( ":" , 0 );
370 }
73eeab33 371}
c6ae69c6 372
73eeab33
PK
373 /*
374 * anyone know a good checksum for ascii files?
375 * this does a rotate-left and then exclusive-or's in the character.
376 * also, it avoids returning checksums of 0.
377 * The rotate is implemented by shifting and adding back the
378 * sign bit when negative.
379 */
380long
381checksum(filename)
382 char *filename;
383{
384 FILE *filep;
385 register int input;
386 register long check;
387
388 filep = fopen(filename, "r");
389 if (filep == NULL) {
390 perror(filename);
391 pexit(DIED);
392 }
393 check = 0;
394 while ((input = getc(filep)) != EOF) {
395 if (check < 0) {
396 check <<= 1;
397 check += 1;
398 } else {
399 check <<= 1;
400 }
401 check ^= input;
402 }
3b091403 403 (void) fclose(filep);
73eeab33
PK
404 if ((unsigned) check <= N_FLAGCHECKSUM) {
405 return N_FLAGCHECKSUM + 1;
406 } else {
407 return check;
408 }
409}
c6ae69c6
PK
410
411/*
412 * global Pascal symbols :
413 * labels, types, constants, and external procedure and function names:
414 * These are used by the separate compilation facility
415 * to be able to check for disjoint header files.
c6ae69c6
PK
416 */
417
b721c131
PK
418 /*
419 * global labels
420 */
99f6998f 421stabglabel( label , line )
b721c131
PK
422 char *label;
423 int line;
c6ae69c6 424 {
c6ae69c6 425
99f6998f 426 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
b1148f06 427 , (int) label , N_PC , N_PGLABEL , ABS( line ) );
c6ae69c6
PK
428 }
429
b721c131
PK
430 /*
431 * global constants
432 */
28424b27
KB
433stabgconst( constant , line )
434 char *constant;
b721c131 435 int line;
c6ae69c6 436 {
c6ae69c6 437
99f6998f 438 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
28424b27 439 , (int) constant , N_PC , N_PGCONST , ABS( line ) );
c6ae69c6
PK
440 }
441
f67e1704
KM
442/*
443 * Generate symbolic information about a constant.
444 */
c6ae69c6 445
c6ae69c6 446 }
f67e1704 447}
c6ae69c6 448
f67e1704
KM
449stabgtype (name, type, line)
450char *name;
451struct nl *type;
452int line;
453{
454 putprintf(" .stabs \"%s\",0x%x,0,0x%x,0x%x" ,
455 0, name, N_PC , N_PGTYPE, ABS(line)
456 );
457 if (oldway == 0) {
458 stabltype(name, type);
459 }
460}
461
462stabltype (name, type)
463char *name;
464struct nl *type;
465{
466 if (opt('g')) {
467 putprintf("\t.stabs\t\"%s:t", 1, name);
468 gentype(type);
469 putprintf("\",0x%x,0,0,0", 0, N_LSYM);
470 }
471}
c6ae69c6 472
b721c131
PK
473 /*
474 * external functions and procedures
475 */
270467f1 476stabefunc( name , typeclass , line )
b721c131 477 char *name;
270467f1 478 int typeclass;
b721c131 479 int line;
c6ae69c6 480 {
b721c131 481 int type;
c6ae69c6 482
270467f1 483 if ( typeclass == FUNC ) {
99f6998f 484 type = N_PEFUNC;
270467f1 485 } else if ( typeclass == PROC ) {
99f6998f 486 type = N_PEPROC;
b721c131
PK
487 } else {
488 return;
c6ae69c6 489 }
99f6998f 490 putprintf( " .stabs \"%s\",0x%x,0,0x%x,0x%x" , 0
b1148f06 491 , (int) name , N_PC , type , ABS( line ) );
c6ae69c6
PK
492 }
493
f67e1704
KM
494/*
495 * Generate type information encoded as a string for dbx.
496 * The fwdptrnum field is used only when the type is a pointer
497 * to a type that isn't known when it was entered. When the
498 * type field is filled for some such tptr, fixfwdtype should
499 * be called to output an equivalencing type definition.
500 */
501
502typedef struct TypeDesc *TypeDesc;
503
504struct TypeDesc {
505 struct nl *tptr;
506 int tnum;
507 int fwdptrnum;
508 TypeDesc chain;
509};
510
511#define TABLESIZE 2003
512
513#define typehash(t) ( ( ((int) t) >> 2 ) % TABLESIZE )
514
515private int tcount = 1;
516private TypeDesc typetable[TABLESIZE];
517
518private TypeDesc tdlookup (t)
519struct nl *t;
520{
521 register TypeDesc td;
522
523 td = typetable[typehash(t)];
524 while (td != NIL && td->tptr != t) {
525 td = td->chain;
526 }
527 return td;
528}
529
530private int typelookup (t)
531struct nl *t;
532{
533 register TypeDesc td;
534 int r;
535
536 td = tdlookup(t);
537 if (td == NIL) {
538 r = 0;
539 } else {
540 r = td->tnum;
541 }
542 return r;
543}
544
545private int entertype (type)
546struct nl *type;
547{
548 register TypeDesc td;
549 register int i;
550
551 td = (TypeDesc) malloc(sizeof(struct TypeDesc));
552 td->tptr = type;
553 td->tnum = tcount;
554 td->fwdptrnum = 0;
555 ++tcount;
556 i = typehash(type);
557 td->chain = typetable[i];
558 typetable[i] = td;
559 return td->tnum;
560}
561
562/*
563 * The in_types table currently contains "boolean", "char", "integer",
564 * "real" and "_nil". (See nl.c for definition.)
565 * The lookup call below will give the TYPE class nl entry for these
566 * types. In each case except _nil, the type field of that entry is a RANGE
567 * class nl entry for the type. Sometimes other symbol table entries
568 * point to the TYPE entry (e.g., when there is a range over the base type),
569 * and other entries point to the RANGE entry (e.g., for a variable of the
570 * given type). We don't really want to distinguish between these uses
571 * in dbx, and since it appears that the RANGE entries are not reused if
572 * a range happens to coincide, we will give the two the same identifying
573 * dbx type number.
574 */
575
576private inittypes()
577{
578 int i;
579 extern char *in_types[];
580 struct nl *p;
581
582 for (i = 0; in_types[i] != NIL; i++) {
583 p = lookup(in_types[i]);
584 if (p != NIL) {
585 entertype(p);
586 if (p->type != NIL) {
587 --tcount; /* see comment above */
588 entertype(p->type);
589 }
590 }
591 }
592}
593
594static genarray (t)
595struct nl *t;
596{
597 register struct nl *p;
598
f67e1704 599 for (p = t->chain; p != NIL; p = p->chain) {
a7081ede 600 putprintf("a", 1);
f67e1704
KM
601 gentype(p);
602 putprintf(";", 1);
603 }
604 gentype(t->type);
605}
606
607/*
608 * Really we should walk through ptr[NL_FIELDLIST] for the fields,
609 * and then do the variant tag and fields separately, but dbx
610 * doesn't support this yet.
611 * So, since all the fields of all the variants are on the chain,
612 * we walk through that. Except that this gives the fields in the
613 * reverse order, so we want to print in reverse order.
614 */
615
616static genrecord (t)
617struct nl *t;
618{
619 putprintf("s%d", 1, t->value[NL_OFFS]);
620 if (t->chain != NIL) {
621 genrecfield(t->chain, 1);
622 }
623 putprintf(";", 1);
624}
625
626static genrecfield (t, n)
627struct nl *t;
628int n;
629{
630 if (t->chain != NULL) {
631 genrecfield(t->chain, n + 1);
632 if (n % 2 == 0) {
633 gencontinue();
634 }
635 }
636 putprintf("%s:", 1, t->symbol);
637 gentype(t->type);
638 putprintf(",%d,%d;", 1, 8*t->value[NL_OFFS], 8*lwidth(t->type));
639}
640
641static genvarnt (t)
642struct nl *t;
643{
644 genrecord(t);
645}
646
647static genptr (t)
648struct nl *t;
649{
650 register TypeDesc td;
651
652 putprintf("*", 1);
653 if (t->type != NIL) {
654 gentype(t->type);
655 } else {
656 /*
657 * unresolved forward pointer: use tcount to represent what is
658 * begin pointed to, to be defined later
659 */
660 td = tdlookup(t);
661 if (td == NIL) {
662 panic("nil ptr in stab.genptr");
663 }
664 td->fwdptrnum = tcount;
665 putprintf("%d", 1, tcount);
666 ++tcount;
667 }
668}
669
670/*
671 * The type t is a pointer which has just had its type field filled.
672 * We need to generate a type stab saying that the number saved
673 * in t's fwdptrnum is the same as the t->type's number
674 */
675
676fixfwdtype (t)
677struct nl *t;
678{
679 register TypeDesc td;
680
681 if (opt('g') && oldway == 0) {
682 td = tdlookup(t);
683 if (td != NIL) {
684 putprintf("\t.stabs\t\":t%d=", 1, td->fwdptrnum);
685 gentype(t->type);
686 putprintf("\",0x%x,0,0,0", 0, N_LSYM);
687 }
688 }
689}
690
691static genenum (t)
692struct nl *t;
693{
694 register struct nl *e;
695 register int i;
696
697 putprintf("e", 1);
698 i = 1;
699 e = t->chain;
700 while (e != NULL) {
701 if (i > 2) {
702 gencontinue();
703 i = 0;
704 }
705 putprintf("%s:%d,", 1, e->symbol, e->range[0]);
706 e = e->chain;
707 ++i;
708 }
709 putprintf(";", 1);
710}
711
712static genset (t)
713struct nl *t;
714{
715 putprintf("S", 1);
716 gentype(t->type);
717}
718
719static genrange (t)
720struct nl *t;
721{
722 putprintf("r", 1);
723 gentype(t->type);
724 putprintf(";%d;%d", 1, t->range[0], t->range[1]);
725}
726
727static genfparam (t)
728struct nl *t;
729{
730 struct nl *p;
731 int count;
732
733 if (t->type != NULL) {
734 putprintf("f", 1);
735 gentype(t->type);
736 putprintf(",", 1);
737 } else {
738 putprintf("p", 1);
739 }
740 count = 0;
741 for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) {
742 ++count;
743 }
744 putprintf("%d;", 1, count);
745 for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) {
746 gentype(p->type);
747 putprintf(",%d;", 1, p->class);
748 }
749}
750
751static genfile (t)
752struct nl *t;
753{
754 putprintf("d", 1);
755 gentype(t->type);
756}
757
758static gentype (t)
759struct nl *t;
760{
761 int id;
762
763 if (tcount == 1) {
764 inittypes();
765 }
766 id = typelookup(t);
767 if (id != 0) {
768 putprintf("%d", 1, id);
769 } else if (t->class == SCAL && t->chain == NULL) {
770 id = typelookup(t->type);
771 if (id != 0) {
772 putprintf("%d", 1, id);
773 } else {
774 genenum(t->type);
775 }
776 } else {
777 id = entertype(t);
778 putprintf("%d=", 1, id);
779 switch (t->class) {
780 case TYPE:
781 gentype(t->type);
782 break;
783
784 case ARRAY:
785 genarray(t);
786 break;
787
788 case RECORD:
789 genrecord(t);
790 break;
791
792 case VARNT:
793 genvarnt(t);
794 break;
795
796 case REF:
797 gentype(t->type);
798 break;
799
800 case PTR:
801 genptr(t);
802 break;
803
804 case SET:
805 genset(t);
806 break;
807
808 case RANGE:
809 genrange(t);
810 break;
811
812 case SCAL:
813 genenum(t);
814 break;
815
816 case FPROC:
817 case FFUNC:
818 genfparam(t);
819 break;
820
821 case FILET:
822 case PTRFILE:
823 genfile(t);
824 break;
825
826 default:
827 /* This shouldn't happen */
828 /* Rather than bomb outright, let debugging go on */
829 warning();
830 error("Bad type class found in stab");
831 putprintf("1", 1, t->class);
832 break;
833 }
834 }
835}
836
837/*
838 * Continue stab information in a namelist new entry. This is necessary
839 * to avoid overflowing putprintf's buffer.
840 */
841
842static gencontinue ()
843{
844 putprintf("?\",0x%x,0,0,0", 0, N_LSYM);
845 putprintf("\t.stabs\t\"", 1);
846}
847
c6ae69c6 848#endif PC