types.c (20851B)
1 #include "c.h" 2 #include <float.h> 3 4 5 static Field isfield(const char *, Field); 6 static Type type(int, Type, int, int, void *); 7 8 static struct entry { 9 struct type type; 10 struct entry *link; 11 } *typetable[128]; 12 static int maxlevel; 13 14 static Symbol pointersym; 15 16 Type chartype; /* char */ 17 Type doubletype; /* double */ 18 Type floattype; /* float */ 19 Type inttype; /* signed int */ 20 Type longdouble; /* long double */ 21 Type longtype; /* long */ 22 Type longlong; /* long long */ 23 Type shorttype; /* signed short int */ 24 Type signedchar; /* signed char */ 25 Type unsignedchar; /* unsigned char */ 26 Type unsignedlong; /* unsigned long int */ 27 Type unsignedlonglong; /* unsigned long long int */ 28 Type unsignedshort; /* unsigned short int */ 29 Type unsignedtype; /* unsigned int */ 30 Type funcptype; /* void (*)() */ 31 Type charptype; /* char* */ 32 Type voidptype; /* void* */ 33 Type voidtype; /* basic types: void */ 34 Type unsignedptr; /* unsigned type to hold void* */ 35 Type signedptr; /* signed type to hold void* */ 36 Type widechar; /* unsigned type that represents wchar_t */ 37 38 static Type xxinit(int op, char *name, Metrics m) { 39 Symbol p = install(string(name), &types, GLOBAL, PERM); 40 Type ty = type(op, 0, m.size, m.align, p); 41 42 assert(ty->align == 0 || ty->size%ty->align == 0); 43 p->type = ty; 44 p->addressed = m.outofline; 45 switch (ty->op) { 46 case INT: 47 p->u.limits.max.i = ones(8*ty->size)>>1; 48 p->u.limits.min.i = -p->u.limits.max.i - 1; 49 break; 50 case UNSIGNED: 51 p->u.limits.max.u = ones(8*ty->size); 52 p->u.limits.min.u = 0; 53 break; 54 case FLOAT: 55 if (ty->size == sizeof (float)) 56 p->u.limits.max.d = FLT_MAX; 57 else if (ty->size == sizeof (double)) 58 p->u.limits.max.d = DBL_MAX; 59 else 60 p->u.limits.max.d = LDBL_MAX; 61 p->u.limits.min.d = -p->u.limits.max.d; 62 break; 63 default: assert(0); 64 } 65 return ty; 66 } 67 static Type type(int op, Type ty, int size, int align, void *sym) { 68 unsigned h = (op^((unsigned long)ty>>3)) 69 &(NELEMS(typetable)-1); 70 struct entry *tn; 71 72 if (op != FUNCTION && (op != ARRAY || size > 0)) 73 for (tn = typetable[h]; tn; tn = tn->link) 74 if (tn->type.op == op && tn->type.type == ty 75 && tn->type.size == size && tn->type.align == align 76 && tn->type.u.sym == sym) 77 return &tn->type; 78 NEW0(tn, PERM); 79 tn->type.op = op; 80 tn->type.type = ty; 81 tn->type.size = size; 82 tn->type.align = align; 83 tn->type.u.sym = sym; 84 tn->link = typetable[h]; 85 typetable[h] = tn; 86 return &tn->type; 87 } 88 void type_init(int argc, char *argv[]) { 89 static int inited; 90 int i; 91 92 if (inited) 93 return; 94 inited = 1; 95 if (!IR) 96 return; 97 for (i = 1; i < argc; i++) { 98 int size, align, outofline; 99 if (strncmp(argv[i], "-unsigned_char=", 15) == 0) 100 IR->unsigned_char = argv[i][15] - '0'; 101 #define xx(name) \ 102 else if (sscanf(argv[i], "-" #name "=%d,%d,%d", &size, &align, &outofline) == 3) { \ 103 IR->name.size = size; IR->name.align = align; \ 104 IR->name.outofline = outofline; } 105 xx(charmetric) 106 xx(shortmetric) 107 xx(intmetric) 108 xx(longmetric) 109 xx(longlongmetric) 110 xx(floatmetric) 111 xx(doublemetric) 112 xx(longdoublemetric) 113 xx(ptrmetric) 114 xx(structmetric) 115 #undef xx 116 } 117 #define xx(v,name,op,metrics) v=xxinit(op,name,IR->metrics) 118 xx(chartype, "char", IR->unsigned_char ? UNSIGNED : INT,charmetric); 119 xx(doubletype, "double", FLOAT, doublemetric); 120 xx(floattype, "float", FLOAT, floatmetric); 121 xx(inttype, "int", INT, intmetric); 122 xx(longdouble, "long double", FLOAT, longdoublemetric); 123 xx(longtype, "long int", INT, longmetric); 124 xx(longlong, "long long int", INT, longlongmetric); 125 xx(shorttype, "short", INT, shortmetric); 126 xx(signedchar, "signed char", INT, charmetric); 127 xx(unsignedchar, "unsigned char", UNSIGNED,charmetric); 128 xx(unsignedlong, "unsigned long", UNSIGNED,longmetric); 129 xx(unsignedshort, "unsigned short", UNSIGNED,shortmetric); 130 xx(unsignedtype, "unsigned int", UNSIGNED,intmetric); 131 xx(unsignedlonglong,"unsigned long long",UNSIGNED,longlongmetric); 132 #undef xx 133 { 134 Symbol p; 135 p = install(string("void"), &types, GLOBAL, PERM); 136 voidtype = type(VOID, NULL, 0, 0, p); 137 p->type = voidtype; 138 } 139 pointersym = install(string("T*"), &types, GLOBAL, PERM); 140 pointersym->addressed = IR->ptrmetric.outofline; 141 pointersym->u.limits.max.p = (void*)ones(8*IR->ptrmetric.size); 142 pointersym->u.limits.min.p = 0; 143 voidptype = ptr(voidtype); 144 funcptype = ptr(func(voidtype, NULL, 1)); 145 charptype = ptr(chartype); 146 #define xx(v,t) if (v==NULL && t->size==voidptype->size && t->align==voidptype->align) v=t 147 xx(unsignedptr,unsignedshort); 148 xx(unsignedptr,unsignedtype); 149 xx(unsignedptr,unsignedlong); 150 xx(unsignedptr,unsignedlonglong); 151 if (unsignedptr == NULL) 152 unsignedptr = type(UNSIGNED, NULL, voidptype->size, voidptype->align, voidptype->u.sym); 153 xx(signedptr,shorttype); 154 xx(signedptr,inttype); 155 xx(signedptr,longtype); 156 xx(signedptr,longlong); 157 if (signedptr == NULL) 158 signedptr = type(INT, NULL, voidptype->size, voidptype->align, voidptype->u.sym); 159 #undef xx 160 widechar = unsignedshort; 161 for (i = 0; i < argc; i++) { 162 #define xx(name,type) \ 163 if (strcmp(argv[i], "-wchar_t=" #name) == 0) \ 164 widechar = type; 165 xx(unsigned_char,unsignedchar) 166 xx(unsigned_int,unsignedtype) 167 xx(unsigned_short,unsignedshort) 168 } 169 #undef xx 170 } 171 void rmtypes(int lev) { 172 if (maxlevel >= lev) { 173 int i; 174 maxlevel = 0; 175 for (i = 0; i < NELEMS(typetable); i++) { 176 struct entry *tn, **tq = &typetable[i]; 177 while ((tn = *tq) != NULL) 178 if (tn->type.op == FUNCTION) 179 tq = &tn->link; 180 else if (tn->type.u.sym && tn->type.u.sym->scope >= lev) 181 *tq = tn->link; 182 else { 183 if (tn->type.u.sym && tn->type.u.sym->scope > maxlevel) 184 maxlevel = tn->type.u.sym->scope; 185 tq = &tn->link; 186 } 187 188 } 189 } 190 } 191 Type ptr(Type ty) { 192 return type(POINTER, ty, IR->ptrmetric.size, 193 IR->ptrmetric.align, pointersym); 194 } 195 Type deref(Type ty) { 196 if (isptr(ty)) 197 ty = ty->type; 198 else 199 error("type error: %s\n", "pointer expected"); 200 return isenum(ty) ? unqual(ty)->type : ty; 201 } 202 Type array(Type ty, int n, int a) { 203 assert(ty); 204 if (isfunc(ty)) { 205 error("illegal type `array of %t'\n", ty); 206 return array(inttype, n, 0); 207 } 208 if (isarray(ty) && ty->size == 0) 209 error("missing array size\n"); 210 if (ty->size == 0) { 211 if (unqual(ty) == voidtype) 212 error("illegal type `array of %t'\n", ty); 213 else if (Aflag >= 2) 214 warning("declaring type array of %t' is undefined\n", ty); 215 216 } else if (n > INT_MAX/ty->size) { 217 error("size of `array of %t' exceeds %d bytes\n", 218 ty, INT_MAX); 219 n = 1; 220 } 221 return type(ARRAY, ty, n*ty->size, 222 a ? a : ty->align, NULL); 223 } 224 Type atop(Type ty) { 225 if (isarray(ty)) 226 return ptr(ty->type); 227 error("type error: %s\n", "array expected"); 228 return ptr(ty); 229 } 230 Type qual(int op, Type ty) { 231 if (isarray(ty)) 232 ty = type(ARRAY, qual(op, ty->type), ty->size, 233 ty->align, NULL); 234 else if (isfunc(ty)) 235 warning("qualified function type ignored\n"); 236 else if (isconst(ty) && op == CONST 237 || isvolatile(ty) && op == VOLATILE) 238 error("illegal type `%k %t'\n", op, ty); 239 else { 240 if (isqual(ty)) { 241 op += ty->op; 242 ty = ty->type; 243 } 244 ty = type(op, ty, ty->size, ty->align, NULL); 245 } 246 return ty; 247 } 248 Type func(Type ty, Type *proto, int style) { 249 if (ty && (isarray(ty) || isfunc(ty))) 250 error("illegal return type `%t'\n", ty); 251 ty = type(FUNCTION, ty, 0, 0, NULL); 252 ty->u.f.proto = proto; 253 ty->u.f.oldstyle = style; 254 return ty; 255 } 256 Type freturn(Type ty) { 257 if (isfunc(ty)) 258 return ty->type; 259 error("type error: %s\n", "function expected"); 260 return inttype; 261 } 262 int variadic(Type ty) { 263 if (isfunc(ty) && ty->u.f.proto) { 264 int i; 265 for (i = 0; ty->u.f.proto[i]; i++) 266 ; 267 return i > 1 && ty->u.f.proto[i-1] == voidtype; 268 } 269 return 0; 270 } 271 Type newstruct(int op, char *tag) { 272 Symbol p; 273 274 assert(tag); 275 if (*tag == 0) 276 tag = stringd(genlabel(1)); 277 else 278 if ((p = lookup(tag, types)) != NULL && (p->scope == level 279 || p->scope == PARAM && level == PARAM+1)) { 280 if (p->type->op == op && !p->defined) 281 return p->type; 282 error("redefinition of `%s' previously defined at %w\n", 283 p->name, &p->src); 284 } 285 p = install(tag, &types, level, PERM); 286 p->type = type(op, NULL, 0, 0, p); 287 if (p->scope > maxlevel) 288 maxlevel = p->scope; 289 p->src = src; 290 return p->type; 291 } 292 Field newfield(char *name, Type ty, Type fty) { 293 Field p, *q = &ty->u.sym->u.s.flist; 294 295 if (name == NULL) 296 name = stringd(genlabel(1)); 297 for (p = *q; p; q = &p->link, p = *q) 298 if (p->name == name) 299 error("duplicate field name `%s' in `%t'\n", 300 name, ty); 301 NEW0(p, PERM); 302 *q = p; 303 p->name = name; 304 p->type = fty; 305 if (xref) { /* omit */ 306 if (ty->u.sym->u.s.ftab == NULL) /* omit */ 307 ty->u.sym->u.s.ftab = table(NULL, level); /* omit */ 308 install(name, &ty->u.sym->u.s.ftab, 0, PERM)->src = src;/* omit */ 309 } /* omit */ 310 return p; 311 } 312 int eqtype(Type ty1, Type ty2, int ret) { 313 if (ty1 == ty2) 314 return 1; 315 if (ty1->op != ty2->op) 316 return 0; 317 switch (ty1->op) { 318 case ENUM: case UNION: case STRUCT: 319 case UNSIGNED: case INT: case FLOAT: 320 return 0; 321 case POINTER: return eqtype(ty1->type, ty2->type, 1); 322 case VOLATILE: case CONST+VOLATILE: 323 case CONST: return eqtype(ty1->type, ty2->type, 1); 324 case ARRAY: if (eqtype(ty1->type, ty2->type, 1)) { 325 if (ty1->size == ty2->size) 326 return 1; 327 if (ty1->size == 0 || ty2->size == 0) 328 return ret; 329 } 330 return 0; 331 case FUNCTION: if (eqtype(ty1->type, ty2->type, 1)) { 332 Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto; 333 if (p1 == p2) 334 return 1; 335 if (p1 && p2) { 336 for ( ; *p1 && *p2; p1++, p2++) 337 if (eqtype(unqual(*p1), unqual(*p2), 1) == 0) 338 return 0; 339 if (*p1 == NULL && *p2 == NULL) 340 return 1; 341 } else { 342 if (variadic(p1 ? ty1 : ty2)) 343 return 0; 344 if (p1 == NULL) 345 p1 = p2; 346 for ( ; *p1; p1++) { 347 Type ty = unqual(*p1); 348 if (promote(ty) != (isenum(ty) ? ty->type : ty)) 349 return 0; 350 } 351 return 1; 352 } 353 } 354 return 0; 355 } 356 assert(0); return 0; 357 } 358 Type promote(Type ty) { 359 ty = unqual(ty); 360 switch (ty->op) { 361 case ENUM: 362 return inttype; 363 case INT: 364 if (ty->size < inttype->size) 365 return inttype; 366 break; 367 case UNSIGNED: 368 if (ty->size < inttype->size) 369 return inttype; 370 if (ty->size < unsignedtype->size) 371 return unsignedtype; 372 break; 373 case FLOAT: 374 if (ty->size < doubletype->size) 375 return doubletype; 376 } 377 return ty; 378 } 379 Type signedint(Type ty) { 380 if (ty->op == INT) 381 return ty; 382 assert(ty->op == UNSIGNED); 383 #define xx(t) if (ty->size == t->size) return t 384 xx(inttype); 385 xx(longtype); 386 xx(longlong); 387 #undef xx 388 assert(0); return NULL; 389 } 390 Type compose(Type ty1, Type ty2) { 391 if (ty1 == ty2) 392 return ty1; 393 assert(ty1->op == ty2->op); 394 switch (ty1->op) { 395 case POINTER: 396 return ptr(compose(ty1->type, ty2->type)); 397 case CONST+VOLATILE: 398 return qual(CONST, qual(VOLATILE, 399 compose(ty1->type, ty2->type))); 400 case CONST: case VOLATILE: 401 return qual(ty1->op, compose(ty1->type, ty2->type)); 402 case ARRAY: { Type ty = compose(ty1->type, ty2->type); 403 if (ty1->size && (ty1->type->size && ty2->size == 0 || ty1->size == ty2->size)) 404 return array(ty, ty1->size/ty1->type->size, ty1->align); 405 if (ty2->size && ty2->type->size && ty1->size == 0) 406 return array(ty, ty2->size/ty2->type->size, ty2->align); 407 return array(ty, 0, 0); } 408 case FUNCTION: { Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto; 409 Type ty = compose(ty1->type, ty2->type); 410 List tlist = NULL; 411 if (p1 == NULL && p2 == NULL) 412 return func(ty, NULL, 1); 413 if (p1 && p2 == NULL) 414 return func(ty, p1, ty1->u.f.oldstyle); 415 if (p2 && p1 == NULL) 416 return func(ty, p2, ty2->u.f.oldstyle); 417 for ( ; *p1 && *p2; p1++, p2++) { 418 Type ty = compose(unqual(*p1), unqual(*p2)); 419 if (isconst(*p1) || isconst(*p2)) 420 ty = qual(CONST, ty); 421 if (isvolatile(*p1) || isvolatile(*p2)) 422 ty = qual(VOLATILE, ty); 423 tlist = append(ty, tlist); 424 } 425 assert(*p1 == NULL && *p2 == NULL); 426 return func(ty, ltov(&tlist, PERM), 0); } 427 } 428 assert(0); return NULL; 429 } 430 int ttob(Type ty) { 431 switch (ty->op) { 432 case CONST: case VOLATILE: case CONST+VOLATILE: 433 return ttob(ty->type); 434 case VOID: case INT: case UNSIGNED: case FLOAT: 435 return ty->op + sizeop(ty->size); 436 case POINTER: 437 return POINTER + sizeop(voidptype->size); 438 case FUNCTION: 439 return POINTER + sizeop(funcptype->size); 440 case ARRAY: case STRUCT: case UNION: 441 return STRUCT; 442 case ENUM: 443 return INT + sizeop(inttype->size); 444 } 445 assert(0); return INT; 446 } 447 Type btot(int op, int size) { 448 #define xx(ty) if (size == (ty)->size) return ty; 449 switch (optype(op)) { 450 case F: 451 xx(floattype); 452 xx(doubletype); 453 xx(longdouble); 454 assert(0); return 0; 455 case I: 456 if (chartype->op == INT) 457 xx(chartype); 458 xx(signedchar); 459 xx(shorttype); 460 xx(inttype); 461 xx(longtype); 462 xx(longlong); 463 assert(0); return 0; 464 case U: 465 if (chartype->op == UNSIGNED) 466 xx(chartype); 467 xx(unsignedchar); 468 xx(unsignedshort); 469 xx(unsignedtype); 470 xx(unsignedlong); 471 xx(unsignedlonglong); 472 assert(0); return 0; 473 case P: 474 xx(voidptype); 475 xx(funcptype); 476 assert(0); return 0; 477 } 478 #undef xx 479 assert(0); return 0; 480 } 481 int hasproto(Type ty) { 482 if (ty == 0) 483 return 1; 484 switch (ty->op) { 485 case CONST: case VOLATILE: case CONST+VOLATILE: case POINTER: 486 case ARRAY: 487 return hasproto(ty->type); 488 case FUNCTION: 489 return hasproto(ty->type) && ty->u.f.proto; 490 case STRUCT: case UNION: 491 case VOID: case FLOAT: case ENUM: case INT: case UNSIGNED: 492 return 1; 493 } 494 assert(0); return 0; 495 } 496 /* fieldlist - construct a flat list of fields in type ty */ 497 Field fieldlist(Type ty) { 498 return ty->u.sym->u.s.flist; 499 } 500 501 /* fieldref - find field name of type ty, return entry */ 502 Field fieldref(const char *name, Type ty) { 503 Field p = isfield(name, unqual(ty)->u.sym->u.s.flist); 504 505 if (p && xref) { 506 Symbol q; 507 assert(unqual(ty)->u.sym->u.s.ftab); 508 q = lookup(name, unqual(ty)->u.sym->u.s.ftab); 509 assert(q); 510 use(q, src); 511 } 512 return p; 513 } 514 515 /* ftype - return a function type for rty function (ty,...)' */ 516 Type ftype(Type rty, Type ty) { 517 List list = append(ty, NULL); 518 519 list = append(voidtype, list); 520 return func(rty, ltov(&list, PERM), 0); 521 } 522 523 /* isfield - if name is a field in flist, return pointer to the field structure */ 524 static Field isfield(const char *name, Field flist) { 525 for ( ; flist; flist = flist->link) 526 if (flist->name == name) 527 break; 528 return flist; 529 } 530 531 /* outtype - output type ty */ 532 void outtype(Type ty, FILE *f) { 533 switch (ty->op) { 534 case CONST+VOLATILE: case CONST: case VOLATILE: 535 fprint(f, "%k %t", ty->op, ty->type); 536 break; 537 case STRUCT: case UNION: case ENUM: 538 assert(ty->u.sym); 539 if (ty->size == 0) 540 fprint(f, "incomplete "); 541 assert(ty->u.sym->name); 542 if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') { 543 Symbol p = findtype(ty); 544 if (p == 0) 545 fprint(f, "%k defined at %w", ty->op, &ty->u.sym->src); 546 else 547 fprint(f, p->name); 548 } else { 549 fprint(f, "%k %s", ty->op, ty->u.sym->name); 550 if (ty->size == 0) 551 fprint(f, " defined at %w", &ty->u.sym->src); 552 } 553 break; 554 case VOID: case FLOAT: case INT: case UNSIGNED: 555 fprint(f, ty->u.sym->name); 556 break; 557 case POINTER: 558 fprint(f, "pointer to %t", ty->type); 559 break; 560 case FUNCTION: 561 fprint(f, "%t function", ty->type); 562 if (ty->u.f.proto && ty->u.f.proto[0]) { 563 int i; 564 fprint(f, "(%t", ty->u.f.proto[0]); 565 for (i = 1; ty->u.f.proto[i]; i++) 566 if (ty->u.f.proto[i] == voidtype) 567 fprint(f, ",..."); 568 else 569 fprint(f, ",%t", ty->u.f.proto[i]); 570 fprint(f, ")"); 571 } else if (ty->u.f.proto && ty->u.f.proto[0] == 0) 572 fprint(f, "(void)"); 573 574 break; 575 case ARRAY: 576 if (ty->size > 0 && ty->type && ty->type->size > 0) { 577 fprint(f, "array %d", ty->size/ty->type->size); 578 while (ty->type && isarray(ty->type) && ty->type->type->size > 0) { 579 ty = ty->type; 580 fprint(f, ",%d", ty->size/ty->type->size); 581 } 582 } else 583 fprint(f, "incomplete array"); 584 if (ty->type) 585 fprint(f, " of %t", ty->type); 586 break; 587 default: assert(0); 588 } 589 } 590 591 /* printdecl - output a C declaration for symbol p of type ty */ 592 void printdecl(Symbol p, Type ty) { 593 switch (p->sclass) { 594 case AUTO: 595 fprint(stderr, "%s;\n", typestring(ty, p->name)); 596 break; 597 case STATIC: case EXTERN: 598 fprint(stderr, "%k %s;\n", p->sclass, typestring(ty, p->name)); 599 break; 600 case TYPEDEF: case ENUM: 601 break; 602 default: assert(0); 603 } 604 } 605 606 /* printproto - output a prototype declaration for function p */ 607 void printproto(Symbol p, Symbol callee[]) { 608 if (p->type->u.f.proto) 609 printdecl(p, p->type); 610 else { 611 int i; 612 List list = 0; 613 if (callee[0] == 0) 614 list = append(voidtype, list); 615 else 616 for (i = 0; callee[i]; i++) 617 list = append(callee[i]->type, list); 618 printdecl(p, func(freturn(p->type), ltov(&list, PERM), 0)); 619 } 620 } 621 622 /* prtype - print details of type ty on f with given indent */ 623 static void prtype(Type ty, FILE *f, int indent, unsigned mark) { 624 switch (ty->op) { 625 default: 626 fprint(f, "(%d %d %d [%p])", ty->op, ty->size, ty->align, ty->u.sym); 627 break; 628 case FLOAT: case INT: case UNSIGNED: case VOID: 629 fprint(f, "(%k %d %d [\"%s\"])", ty->op, ty->size, ty->align, ty->u.sym->name); 630 break; 631 case CONST+VOLATILE: case CONST: case VOLATILE: case POINTER: case ARRAY: 632 fprint(f, "(%k %d %d ", ty->op, ty->size, ty->align); 633 prtype(ty->type, f, indent+1, mark); 634 fprint(f, ")"); 635 break; 636 case STRUCT: case UNION: 637 fprint(f, "(%k %d %d [\"%s\"]", ty->op, ty->size, ty->align, ty->u.sym->name); 638 if (ty->x.marked != mark) { 639 Field p; 640 ty->x.marked = mark; 641 for (p = ty->u.sym->u.s.flist; p; p = p->link) { 642 fprint(f, "\n%I", indent+1); 643 prtype(p->type, f, indent+1, mark); 644 fprint(f, " %s@%d", p->name, p->offset); 645 if (p->lsb) 646 fprint(f, ":%d..%d", 647 fieldsize(p) + fieldright(p), fieldright(p)); 648 } 649 fprint(f, "\n%I", indent); 650 } 651 fprint(f, ")"); 652 break; 653 case ENUM: 654 fprint(f, "(%k %d %d [\"%s\"]", ty->op, ty->size, ty->align, ty->u.sym->name); 655 if (ty->x.marked != mark) { 656 int i; 657 Symbol *p = ty->u.sym->u.idlist; 658 ty->x.marked = mark; 659 for (i = 0; p[i] != NULL; i++) 660 fprint(f, "%I%s=%d\n", indent+1, p[i]->name, p[i]->u.value); 661 } 662 fprint(f, ")"); 663 break; 664 case FUNCTION: 665 fprint(f, "(%k %d %d ", ty->op, ty->size, ty->align); 666 prtype(ty->type, f, indent+1, mark); 667 if (ty->u.f.proto) { 668 int i; 669 fprint(f, "\n%I{", indent+1); 670 for (i = 0; ty->u.f.proto[i]; i++) { 671 if (i > 0) 672 fprint(f, "%I", indent+2); 673 prtype(ty->u.f.proto[i], f, indent+2, mark); 674 fprint(f, "\n"); 675 } 676 fprint(f, "%I}", indent+1); 677 } 678 fprint(f, ")"); 679 break; 680 } 681 } 682 683 /* printtype - print details of type ty on fd */ 684 void printtype(Type ty, int fd) { 685 static unsigned mark; 686 prtype(ty, fd == 1 ? stdout : stderr, 0, ++mark); 687 fprint(fd == 1 ? stdout : stderr, "\n"); 688 } 689 690 /* typestring - return ty as C declaration for str, which may be "" */ 691 char *typestring(Type ty, char *str) { 692 for ( ; ty; ty = ty->type) { 693 Symbol p; 694 switch (ty->op) { 695 case CONST+VOLATILE: case CONST: case VOLATILE: 696 if (isptr(ty->type)) 697 str = stringf("%k %s", ty->op, str); 698 else 699 return stringf("%k %s", ty->op, typestring(ty->type, str)); 700 break; 701 case STRUCT: case UNION: case ENUM: 702 assert(ty->u.sym); 703 if ((p = findtype(ty)) != NULL) 704 return *str ? stringf("%s %s", p->name, str) : p->name; 705 if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') 706 warning("unnamed %k in prototype\n", ty->op); 707 if (*str) 708 return stringf("%k %s %s", ty->op, ty->u.sym->name, str); 709 else 710 return stringf("%k %s", ty->op, ty->u.sym->name); 711 case VOID: case FLOAT: case INT: case UNSIGNED: 712 return *str ? stringf("%s %s", ty->u.sym->name, str) : ty->u.sym->name; 713 case POINTER: 714 if (!ischar(ty->type) && (p = findtype(ty)) != NULL) 715 return *str ? stringf("%s %s", p->name, str) : p->name; 716 str = stringf(isarray(ty->type) || isfunc(ty->type) ? "(*%s)" : "*%s", str); 717 break; 718 case FUNCTION: 719 if ((p = findtype(ty)) != NULL) 720 return *str ? stringf("%s %s", p->name, str) : p->name; 721 if (ty->u.f.proto == 0) 722 str = stringf("%s()", str); 723 else if (ty->u.f.proto[0]) { 724 int i; 725 str = stringf("%s(%s", str, typestring(ty->u.f.proto[0], "")); 726 for (i = 1; ty->u.f.proto[i]; i++) 727 if (ty->u.f.proto[i] == voidtype) 728 str = stringf("%s, ...", str); 729 else 730 str = stringf("%s, %s", str, typestring(ty->u.f.proto[i], "")); 731 str = stringf("%s)", str); 732 } else 733 str = stringf("%s(void)", str); 734 break; 735 case ARRAY: 736 if ((p = findtype(ty)) != NULL) 737 return *str ? stringf("%s %s", p->name, str) : p->name; 738 if (ty->type && ty->type->size > 0) 739 str = stringf("%s[%d]", str, ty->size/ty->type->size); 740 else 741 str = stringf("%s[]", str); 742 break; 743 default: assert(0); 744 } 745 } 746 assert(0); return 0; 747 } 748