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

Defined functions

checksum defined in line 379; used 2 times
entertype defined in line 563; used 3 times
fixfwdtype defined in line 694; used 1 times
genarray defined in line 612; used 1 times
gencontinue defined in line 860; used 2 times
genenum defined in line 709; used 2 times
genfile defined in line 769; used 1 times
genfparam defined in line 745; used 1 times
genptr defined in line 665; used 1 times
genrange defined in line 737; used 1 times
genrecfield defined in line 644; used 2 times
genrecord defined in line 634; used 2 times
genset defined in line 730; used 1 times
gentype defined in line 776; used 18 times
genvarnt defined in line 659; used 1 times
inittypes defined in line 594; used 1 times
oldstabfunc defined in line 262; used 1 times
oldstabgvar defined in line 85; used 1 times
  • in line 57
oldstablvar defined in line 107; used 1 times
  • in line 73
oldstabparam defined in line 148; used 1 times
snestspec defined in line 237; used 1 times
stabefunc defined in line 494; used 1 times
stabfunc defined in line 197; used 2 times
stabgconst defined in line 432; used 1 times
stabglabel defined in line 420; used 1 times
stabgtype defined in line 467; used 1 times
stabgvar defined in line 49; used 1 times
stabinclude defined in line 338; used 2 times
stablbrac defined in line 174; used 1 times
stabltype defined in line 480; used 2 times
stablvar defined in line 65; used 2 times
stabparam defined in line 127; used 1 times
stabrbrac defined in line 187; used 1 times
tdlookup defined in line 536; used 3 times
typelookup defined in line 548; used 2 times

Defined variables

oldway defined in line 37; used 11 times
sccsid defined in line 8; never used
tcount defined in line 533; used 7 times
typetable defined in line 534; used 3 times

Defined struct's

TypeDesc defined in line 522; used 3 times

Defined typedef's

TypeDesc defined in line 520; used 9 times

Defined macros

ABS defined in line 42; used 8 times
TABLESIZE defined in line 529; used 2 times
private defined in line 35; used 7 times
typehash defined in line 531; used 2 times
Last modified: 1985-11-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5199
Valid CSS Valid XHTML 1.0 Strict