1*9659Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*9659Slinton 3*9659Slinton static char sccsid[] = "@(#)@(#)c.c 1.1 12/15/82"; 4*9659Slinton 5*9659Slinton /* 6*9659Slinton * C-dependent symbol routines. 7*9659Slinton */ 8*9659Slinton 9*9659Slinton #include "defs.h" 10*9659Slinton #include "symbols.h" 11*9659Slinton #include "printsym.h" 12*9659Slinton #include "languages.h" 13*9659Slinton #include "c.h" 14*9659Slinton #include "tree.h" 15*9659Slinton #include "eval.h" 16*9659Slinton #include "operators.h" 17*9659Slinton #include "mappings.h" 18*9659Slinton #include "process.h" 19*9659Slinton #include "runtime.h" 20*9659Slinton #include "machine.h" 21*9659Slinton 22*9659Slinton #define isdouble(range) ( \ 23*9659Slinton range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \ 24*9659Slinton ) 25*9659Slinton 26*9659Slinton #define isrange(t, name) (t->class == RANGE and istypename(t->type, name)) 27*9659Slinton 28*9659Slinton /* 29*9659Slinton * Initialize C language information. 30*9659Slinton */ 31*9659Slinton 32*9659Slinton public c_init() 33*9659Slinton { 34*9659Slinton Language lang; 35*9659Slinton 36*9659Slinton lang = language_define("c", ".c"); 37*9659Slinton language_setop(lang, L_PRINTDECL, c_printdecl); 38*9659Slinton language_setop(lang, L_PRINTVAL, c_printval); 39*9659Slinton language_setop(lang, L_TYPEMATCH, c_typematch); 40*9659Slinton } 41*9659Slinton 42*9659Slinton /* 43*9659Slinton * Test if two types are compatible. 44*9659Slinton * 45*9659Slinton * Integers and reals are not compatible since they cannot always be mixed. 46*9659Slinton */ 47*9659Slinton 48*9659Slinton public Boolean c_typematch(type1, type2) 49*9659Slinton Symbol type1, type2; 50*9659Slinton { 51*9659Slinton Boolean b; 52*9659Slinton register Symbol t1, t2, tmp; 53*9659Slinton 54*9659Slinton t1 = type1; 55*9659Slinton t2 = type2; 56*9659Slinton if (t1 == t2) { 57*9659Slinton b = true; 58*9659Slinton } else { 59*9659Slinton t1 = rtype(t1); 60*9659Slinton t2 = rtype(t2); 61*9659Slinton if (t1->type == t_int or t1->type == t_char) { 62*9659Slinton tmp = t1; 63*9659Slinton t1 = t2; 64*9659Slinton t2 = tmp; 65*9659Slinton } 66*9659Slinton b = (Boolean) ( 67*9659Slinton ( 68*9659Slinton isrange(t1, "int") and 69*9659Slinton (t2->type == t_int or t2->type == t_char) 70*9659Slinton ) or ( 71*9659Slinton isrange(t1, "char") and 72*9659Slinton (t2->type == t_char or t2->type == t_int) 73*9659Slinton ) or ( 74*9659Slinton t1->type == t2->type and ( 75*9659Slinton (t1->class == t2->class) or 76*9659Slinton (t1->class == SCAL and t2->class == CONST) or 77*9659Slinton (t1->class == CONST and t2->class == SCAL) 78*9659Slinton ) 79*9659Slinton ) 80*9659Slinton ); 81*9659Slinton } 82*9659Slinton return b; 83*9659Slinton } 84*9659Slinton 85*9659Slinton /* 86*9659Slinton * Decide if a field is a bit field. 87*9659Slinton */ 88*9659Slinton 89*9659Slinton private Boolean isbitfield(s) 90*9659Slinton register Symbol s; 91*9659Slinton { 92*9659Slinton Boolean b; 93*9659Slinton register Integer off, len; 94*9659Slinton register Symbol t; 95*9659Slinton 96*9659Slinton off = s->symvalue.field.offset; 97*9659Slinton len = s->symvalue.field.length; 98*9659Slinton if ((off mod BITSPERBYTE) != 0 or (len mod BITSPERBYTE) != 0) { 99*9659Slinton b = true; 100*9659Slinton } else { 101*9659Slinton t = rtype(s->type); 102*9659Slinton b = (Boolean) 103*9659Slinton (t->class == SCAL and len != (sizeof(int)*BITSPERBYTE) or 104*9659Slinton len != (size(t)*BITSPERBYTE) 105*9659Slinton ); 106*9659Slinton } 107*9659Slinton return b; 108*9659Slinton } 109*9659Slinton 110*9659Slinton /* 111*9659Slinton * Print out the declaration of a C variable. 112*9659Slinton */ 113*9659Slinton 114*9659Slinton public c_printdecl(s) 115*9659Slinton Symbol s; 116*9659Slinton { 117*9659Slinton printdecl(s, 0); 118*9659Slinton } 119*9659Slinton 120*9659Slinton private printdecl(s, indent) 121*9659Slinton register Symbol s; 122*9659Slinton Integer indent; 123*9659Slinton { 124*9659Slinton register Symbol t; 125*9659Slinton Boolean semicolon, newline; 126*9659Slinton 127*9659Slinton semicolon = true; 128*9659Slinton newline = true; 129*9659Slinton if (indent > 0) { 130*9659Slinton printf("%*c", indent, ' '); 131*9659Slinton } 132*9659Slinton if (s->class == TYPE) { 133*9659Slinton printf("typedef "); 134*9659Slinton } 135*9659Slinton switch (s->class) { 136*9659Slinton case CONST: 137*9659Slinton if (s->type->class == SCAL) { 138*9659Slinton printf("(enumeration constant, ord %ld)", 139*9659Slinton s->symvalue.iconval); 140*9659Slinton } else { 141*9659Slinton printf("const %s = ", symname(s)); 142*9659Slinton printval(s); 143*9659Slinton } 144*9659Slinton break; 145*9659Slinton 146*9659Slinton case TYPE: 147*9659Slinton case VAR: 148*9659Slinton if (s->class != TYPE) { 149*9659Slinton if (s->level == 2) { 150*9659Slinton printf("static "); 151*9659Slinton } else if (s->level < 0) { 152*9659Slinton printf("register "); 153*9659Slinton } 154*9659Slinton } 155*9659Slinton if (s->type->class == ARRAY) { 156*9659Slinton printtype(s->type, s->type->type, indent); 157*9659Slinton t = rtype(s->type->chain); 158*9659Slinton assert(t->class == RANGE); 159*9659Slinton printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1); 160*9659Slinton } else { 161*9659Slinton printtype(s, s->type, indent); 162*9659Slinton if (s->type->class != PTR) { 163*9659Slinton printf(" "); 164*9659Slinton } 165*9659Slinton printf("%s", symname(s)); 166*9659Slinton } 167*9659Slinton break; 168*9659Slinton 169*9659Slinton case FIELD: 170*9659Slinton if (s->type->class == ARRAY) { 171*9659Slinton printtype(s->type, s->type->type, indent); 172*9659Slinton t = rtype(s->type->chain); 173*9659Slinton assert(t->class == RANGE); 174*9659Slinton printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1); 175*9659Slinton } else { 176*9659Slinton printtype(s, s->type, indent); 177*9659Slinton if (s->type->class != PTR) { 178*9659Slinton printf(" "); 179*9659Slinton } 180*9659Slinton printf("%s", symname(s)); 181*9659Slinton } 182*9659Slinton if (isbitfield(s)) { 183*9659Slinton printf(" : %d", s->symvalue.field.length); 184*9659Slinton } 185*9659Slinton break; 186*9659Slinton 187*9659Slinton case TAG: 188*9659Slinton if (s->type == nil) { 189*9659Slinton findtype(s); 190*9659Slinton if (s->type == nil) { 191*9659Slinton error("unexpected missing type information"); 192*9659Slinton } 193*9659Slinton } 194*9659Slinton printtype(s, s->type, indent); 195*9659Slinton break; 196*9659Slinton 197*9659Slinton case RANGE: 198*9659Slinton case ARRAY: 199*9659Slinton case RECORD: 200*9659Slinton case VARNT: 201*9659Slinton case PTR: 202*9659Slinton semicolon = false; 203*9659Slinton printtype(s, s, indent); 204*9659Slinton break; 205*9659Slinton 206*9659Slinton case PROC: 207*9659Slinton semicolon = false; 208*9659Slinton printf("%s", symname(s)); 209*9659Slinton c_listparams(s); 210*9659Slinton newline = false; 211*9659Slinton break; 212*9659Slinton 213*9659Slinton case FUNC: 214*9659Slinton semicolon = false; 215*9659Slinton if (not istypename(s->type, "void")) { 216*9659Slinton printtype(s, s->type, indent); 217*9659Slinton printf(" "); 218*9659Slinton } 219*9659Slinton printf("%s", symname(s)); 220*9659Slinton c_listparams(s); 221*9659Slinton newline = false; 222*9659Slinton break; 223*9659Slinton 224*9659Slinton case MODULE: 225*9659Slinton semicolon = false; 226*9659Slinton printf("source file \"%s.c\"", symname(s)); 227*9659Slinton break; 228*9659Slinton 229*9659Slinton case PROG: 230*9659Slinton semicolon = false; 231*9659Slinton printf("executable file \"%s\"", symname(s)); 232*9659Slinton break; 233*9659Slinton 234*9659Slinton default: 235*9659Slinton error("class %s in c_printdecl", classname(s)); 236*9659Slinton } 237*9659Slinton if (semicolon) { 238*9659Slinton putchar(';'); 239*9659Slinton } 240*9659Slinton if (newline) { 241*9659Slinton putchar('\n'); 242*9659Slinton } 243*9659Slinton } 244*9659Slinton 245*9659Slinton /* 246*9659Slinton * Recursive whiz-bang procedure to print the type portion 247*9659Slinton * of a declaration. 248*9659Slinton * 249*9659Slinton * The symbol associated with the type is passed to allow 250*9659Slinton * searching for type names without getting "type blah = blah". 251*9659Slinton */ 252*9659Slinton 253*9659Slinton private printtype(s, t, indent) 254*9659Slinton Symbol s; 255*9659Slinton Symbol t; 256*9659Slinton Integer indent; 257*9659Slinton { 258*9659Slinton register Symbol i; 259*9659Slinton long r0, r1; 260*9659Slinton register String p; 261*9659Slinton 262*9659Slinton checkref(s); 263*9659Slinton checkref(t); 264*9659Slinton switch (t->class) { 265*9659Slinton case VAR: 266*9659Slinton case CONST: 267*9659Slinton case PROC: 268*9659Slinton panic("printtype: class %s", classname(t)); 269*9659Slinton break; 270*9659Slinton 271*9659Slinton case ARRAY: 272*9659Slinton printf("array["); 273*9659Slinton i = t->chain; 274*9659Slinton if (i != nil) { 275*9659Slinton for (;;) { 276*9659Slinton printtype(i, i, indent); 277*9659Slinton i = i->chain; 278*9659Slinton if (i == nil) { 279*9659Slinton break; 280*9659Slinton } 281*9659Slinton printf(", "); 282*9659Slinton } 283*9659Slinton } 284*9659Slinton printf("] of "); 285*9659Slinton printtype(t, t->type, indent); 286*9659Slinton break; 287*9659Slinton 288*9659Slinton case RECORD: 289*9659Slinton case VARNT: 290*9659Slinton printf("%s ", c_classname(t)); 291*9659Slinton if (s->name != nil and s->class == TAG) { 292*9659Slinton p = symname(s); 293*9659Slinton if (p[0] == '$' and p[1] == '$') { 294*9659Slinton printf("%s ", &p[2]); 295*9659Slinton } else { 296*9659Slinton printf("%s ", p); 297*9659Slinton } 298*9659Slinton } 299*9659Slinton printf("{\n", t->class == RECORD ? "struct" : "union"); 300*9659Slinton for (i = t->chain; i != nil; i = i->chain) { 301*9659Slinton assert(i->class == FIELD); 302*9659Slinton printdecl(i, indent+4); 303*9659Slinton } 304*9659Slinton if (indent > 0) { 305*9659Slinton printf("%*c", indent, ' '); 306*9659Slinton } 307*9659Slinton printf("}"); 308*9659Slinton break; 309*9659Slinton 310*9659Slinton case RANGE: 311*9659Slinton r0 = t->symvalue.rangev.lower; 312*9659Slinton r1 = t->symvalue.rangev.upper; 313*9659Slinton if (istypename(t->type, "char")) { 314*9659Slinton if (r0 < 0x20 or r0 > 0x7e) { 315*9659Slinton printf("%ld..", r0); 316*9659Slinton } else { 317*9659Slinton printf("'%c'..", (char) r0); 318*9659Slinton } 319*9659Slinton if (r1 < 0x20 or r1 > 0x7e) { 320*9659Slinton printf("\\%lo", r1); 321*9659Slinton } else { 322*9659Slinton printf("'%c'", (char) r1); 323*9659Slinton } 324*9659Slinton } else if (r0 > 0 and r1 == 0) { 325*9659Slinton printf("%ld byte real", r0); 326*9659Slinton } else if (r0 >= 0) { 327*9659Slinton printf("%lu..%lu", r0, r1); 328*9659Slinton } else { 329*9659Slinton printf("%ld..%ld", r0, r1); 330*9659Slinton } 331*9659Slinton break; 332*9659Slinton 333*9659Slinton case PTR: 334*9659Slinton printtype(t, t->type, indent); 335*9659Slinton if (t->type->class != PTR) { 336*9659Slinton printf(" "); 337*9659Slinton } 338*9659Slinton printf("*"); 339*9659Slinton break; 340*9659Slinton 341*9659Slinton case FUNC: 342*9659Slinton printtype(t, t->type, indent); 343*9659Slinton printf("()"); 344*9659Slinton break; 345*9659Slinton 346*9659Slinton case TYPE: 347*9659Slinton if (t->name != nil) { 348*9659Slinton printname(stdout, t); 349*9659Slinton } else { 350*9659Slinton printtype(t, t->type, indent); 351*9659Slinton } 352*9659Slinton break; 353*9659Slinton 354*9659Slinton case TYPEREF: 355*9659Slinton printf("@%s", symname(t)); 356*9659Slinton break; 357*9659Slinton 358*9659Slinton case SCAL: 359*9659Slinton printf("enum "); 360*9659Slinton if (s->name != nil and s->class == TAG) { 361*9659Slinton printf("%s ", symname(s)); 362*9659Slinton } 363*9659Slinton printf("{ "); 364*9659Slinton i = t->chain; 365*9659Slinton if (i != nil) { 366*9659Slinton for (;;) { 367*9659Slinton printf("%s", symname(i)); 368*9659Slinton i = i->chain; 369*9659Slinton if (i == nil) break; 370*9659Slinton printf(", "); 371*9659Slinton } 372*9659Slinton } 373*9659Slinton printf(" }"); 374*9659Slinton break; 375*9659Slinton 376*9659Slinton case TAG: 377*9659Slinton if (t->type == nil) { 378*9659Slinton printf("unresolved tag %s", symname(t)); 379*9659Slinton } else { 380*9659Slinton i = rtype(t->type); 381*9659Slinton printf("%s %s", c_classname(i), symname(t)); 382*9659Slinton } 383*9659Slinton break; 384*9659Slinton 385*9659Slinton default: 386*9659Slinton printf("(class %d)", t->class); 387*9659Slinton break; 388*9659Slinton } 389*9659Slinton } 390*9659Slinton 391*9659Slinton /* 392*9659Slinton * List the parameters of a procedure or function. 393*9659Slinton * No attempt is made to combine like types. 394*9659Slinton */ 395*9659Slinton 396*9659Slinton public c_listparams(s) 397*9659Slinton Symbol s; 398*9659Slinton { 399*9659Slinton register Symbol t; 400*9659Slinton 401*9659Slinton putchar('('); 402*9659Slinton for (t = s->chain; t != nil; t = t->chain) { 403*9659Slinton printf("%s", symname(t)); 404*9659Slinton if (t->chain != nil) { 405*9659Slinton printf(", "); 406*9659Slinton } 407*9659Slinton } 408*9659Slinton putchar(')'); 409*9659Slinton if (s->chain != nil) { 410*9659Slinton printf("\n"); 411*9659Slinton for (t = s->chain; t != nil; t = t->chain) { 412*9659Slinton if (t->class != VAR) { 413*9659Slinton panic("unexpected class %d for parameter", t->class); 414*9659Slinton } 415*9659Slinton printdecl(t, 0); 416*9659Slinton } 417*9659Slinton } else { 418*9659Slinton putchar('\n'); 419*9659Slinton } 420*9659Slinton } 421*9659Slinton 422*9659Slinton /* 423*9659Slinton * Print out the value on the top of the expression stack 424*9659Slinton * in the format for the type of the given symbol. 425*9659Slinton */ 426*9659Slinton 427*9659Slinton public c_printval(s) 428*9659Slinton Symbol s; 429*9659Slinton { 430*9659Slinton register Symbol t; 431*9659Slinton register Address a; 432*9659Slinton register int i, len; 433*9659Slinton 434*9659Slinton switch (s->class) { 435*9659Slinton case CONST: 436*9659Slinton case TYPE: 437*9659Slinton case VAR: 438*9659Slinton case REF: 439*9659Slinton case FVAR: 440*9659Slinton case TAG: 441*9659Slinton c_printval(s->type); 442*9659Slinton break; 443*9659Slinton 444*9659Slinton case FIELD: 445*9659Slinton if (isbitfield(s)) { 446*9659Slinton len = s->symvalue.field.length; 447*9659Slinton if (len <= BITSPERBYTE) { 448*9659Slinton i = pop(char); 449*9659Slinton } else if (len <= sizeof(short)*BITSPERBYTE) { 450*9659Slinton i = pop(short); 451*9659Slinton } else { 452*9659Slinton i = pop(long); 453*9659Slinton } 454*9659Slinton i >>= (s->symvalue.field.offset mod BITSPERBYTE); 455*9659Slinton i &= ((1 << len) - 1); 456*9659Slinton t = rtype(s->type); 457*9659Slinton if (t->class == SCAL) { 458*9659Slinton printenum(i, t); 459*9659Slinton } else { 460*9659Slinton printrange(i, t); 461*9659Slinton } 462*9659Slinton } else { 463*9659Slinton c_printval(s->type); 464*9659Slinton } 465*9659Slinton break; 466*9659Slinton 467*9659Slinton case ARRAY: 468*9659Slinton t = rtype(s->type); 469*9659Slinton if (t->class == RANGE and istypename(t->type, "char")) { 470*9659Slinton len = size(s); 471*9659Slinton sp -= len; 472*9659Slinton printf("\"%.*s\"", len, sp); 473*9659Slinton } else { 474*9659Slinton printarray(s); 475*9659Slinton } 476*9659Slinton break; 477*9659Slinton 478*9659Slinton case RECORD: 479*9659Slinton case VARNT: 480*9659Slinton c_printstruct(s); 481*9659Slinton break; 482*9659Slinton 483*9659Slinton case RANGE: 484*9659Slinton if (istypename(s->type, "boolean")) { 485*9659Slinton printrange(popsmall(s), s); 486*9659Slinton } else if (istypename(s->type, "char")) { 487*9659Slinton printrange(pop(char), s); 488*9659Slinton } else if (isdouble(s)) { 489*9659Slinton switch (s->symvalue.rangev.lower) { 490*9659Slinton case sizeof(float): 491*9659Slinton prtreal(pop(float)); 492*9659Slinton break; 493*9659Slinton 494*9659Slinton case sizeof(double): 495*9659Slinton prtreal(pop(double)); 496*9659Slinton break; 497*9659Slinton 498*9659Slinton default: 499*9659Slinton panic("bad real size %d", t->symvalue.rangev.lower); 500*9659Slinton break; 501*9659Slinton } 502*9659Slinton } else { 503*9659Slinton printrange(popsmall(s), s); 504*9659Slinton } 505*9659Slinton break; 506*9659Slinton 507*9659Slinton case PTR: 508*9659Slinton t = rtype(s->type); 509*9659Slinton a = pop(Address); 510*9659Slinton if (a == 0) { 511*9659Slinton printf("(nil)"); 512*9659Slinton } else if (t->class == RANGE and istypename(t->type, "char")) { 513*9659Slinton printstring(a); 514*9659Slinton } else { 515*9659Slinton printf("0x%x", a); 516*9659Slinton } 517*9659Slinton break; 518*9659Slinton 519*9659Slinton case SCAL: 520*9659Slinton i = pop(Integer); 521*9659Slinton printenum(i, s); 522*9659Slinton break; 523*9659Slinton 524*9659Slinton default: 525*9659Slinton if (ord(s->class) > ord(TYPEREF)) { 526*9659Slinton panic("printval: bad class %d", ord(s->class)); 527*9659Slinton } 528*9659Slinton error("don't know how to print a %s", c_classname(s)); 529*9659Slinton /* NOTREACHED */ 530*9659Slinton } 531*9659Slinton } 532*9659Slinton 533*9659Slinton /* 534*9659Slinton * Print out a C structure. 535*9659Slinton */ 536*9659Slinton 537*9659Slinton private c_printstruct(s) 538*9659Slinton Symbol s; 539*9659Slinton { 540*9659Slinton register Symbol f; 541*9659Slinton register Stack *savesp; 542*9659Slinton register Integer n, off, len; 543*9659Slinton 544*9659Slinton sp -= size(s); 545*9659Slinton savesp = sp; 546*9659Slinton printf("("); 547*9659Slinton f = s->chain; 548*9659Slinton for (;;) { 549*9659Slinton off = f->symvalue.field.offset; 550*9659Slinton len = f->symvalue.field.length; 551*9659Slinton n = (off + len + 7) div BITSPERBYTE; 552*9659Slinton sp += n; 553*9659Slinton printf("%s = ", symname(f)); 554*9659Slinton c_printval(f); 555*9659Slinton sp = savesp; 556*9659Slinton f = f->chain; 557*9659Slinton if (f == nil) break; 558*9659Slinton printf(", "); 559*9659Slinton } 560*9659Slinton printf(")"); 561*9659Slinton } 562*9659Slinton 563*9659Slinton /* 564*9659Slinton * Print out a range type (integer, char, or boolean). 565*9659Slinton */ 566*9659Slinton 567*9659Slinton private printrange(i, t) 568*9659Slinton Integer i; 569*9659Slinton register Symbol t; 570*9659Slinton { 571*9659Slinton if (istypename(t->type, "boolean")) { 572*9659Slinton printf(((Boolean) i) == true ? "true" : "false"); 573*9659Slinton } else if (istypename(t->type, "char")) { 574*9659Slinton putchar('\''); 575*9659Slinton printchar(i); 576*9659Slinton putchar('\''); 577*9659Slinton } else if (t->symvalue.rangev.lower >= 0) { 578*9659Slinton printf("%lu", i); 579*9659Slinton } else { 580*9659Slinton printf("%ld", i); 581*9659Slinton } 582*9659Slinton } 583*9659Slinton 584*9659Slinton /* 585*9659Slinton * Print out a null-terminated string (pointer to char) 586*9659Slinton * starting at the given address. 587*9659Slinton */ 588*9659Slinton 589*9659Slinton private printstring(addr) 590*9659Slinton Address addr; 591*9659Slinton { 592*9659Slinton register Address a; 593*9659Slinton register Integer i, len; 594*9659Slinton register Boolean endofstring; 595*9659Slinton union { 596*9659Slinton char ch[sizeof(Word)]; 597*9659Slinton int word; 598*9659Slinton } u; 599*9659Slinton 600*9659Slinton putchar('"'); 601*9659Slinton a = addr; 602*9659Slinton endofstring = false; 603*9659Slinton while (not endofstring) { 604*9659Slinton dread(&u, a, sizeof(u)); 605*9659Slinton i = 0; 606*9659Slinton do { 607*9659Slinton if (u.ch[i] == '\0') { 608*9659Slinton endofstring = true; 609*9659Slinton } else { 610*9659Slinton printchar(u.ch[i]); 611*9659Slinton } 612*9659Slinton ++i; 613*9659Slinton } while (i < sizeof(Word) and not endofstring); 614*9659Slinton a += sizeof(Word); 615*9659Slinton } 616*9659Slinton putchar('"'); 617*9659Slinton } 618*9659Slinton 619*9659Slinton /* 620*9659Slinton * Print out an enumerated value by finding the corresponding 621*9659Slinton * name in the enumeration list. 622*9659Slinton */ 623*9659Slinton 624*9659Slinton private printenum(i, t) 625*9659Slinton Integer i; 626*9659Slinton Symbol t; 627*9659Slinton { 628*9659Slinton register Symbol e; 629*9659Slinton 630*9659Slinton e = t->chain; 631*9659Slinton while (e != nil and e->symvalue.iconval != i) { 632*9659Slinton e = e->chain; 633*9659Slinton } 634*9659Slinton if (e != nil) { 635*9659Slinton printf("%s", symname(e)); 636*9659Slinton } else { 637*9659Slinton printf("%d", i); 638*9659Slinton } 639*9659Slinton } 640*9659Slinton 641*9659Slinton /* 642*9659Slinton * Return the C name for the particular class of a symbol. 643*9659Slinton */ 644*9659Slinton 645*9659Slinton public String c_classname(s) 646*9659Slinton Symbol s; 647*9659Slinton { 648*9659Slinton String str; 649*9659Slinton 650*9659Slinton switch (s->class) { 651*9659Slinton case RECORD: 652*9659Slinton str = "struct"; 653*9659Slinton break; 654*9659Slinton 655*9659Slinton case VARNT: 656*9659Slinton str = "union"; 657*9659Slinton break; 658*9659Slinton 659*9659Slinton case SCAL: 660*9659Slinton str = "enum"; 661*9659Slinton break; 662*9659Slinton 663*9659Slinton default: 664*9659Slinton str = classname(s); 665*9659Slinton } 666*9659Slinton return str; 667*9659Slinton } 668