1: // Copyright (C) 1985-1998 by Symantec 2: // Copyright (C) 2000-2009 by Digital Mars 3: // All Rights Reserved 4: // http://www.digitalmars.com 5: // Written by Walter Bright 6: /* 7: * This source file is made available for personal use 8: * only. The license is in /dmd/src/dmd/backendlicense.txt 9: * or /dm/src/dmd/backendlicense.txt 10: * For any other uses, please contact Digital Mars. 11: */ 12: 13: #if !SPP 14: 15: #include <stdio.h> 16: #include <string.h> 17: #include <time.h> 18: 19: #include "cc.h" 20: #include "global.h" 21: #include "type.h" 22: #include "el.h" 23: 24: #if SCPP 25: #include "parser.h" 26: #endif 27: 28: #undef MEM_PH_MALLOC 29: #define MEM_PH_MALLOC mem_fmalloc 30: 31: static char __file__[] = __FILE__; /* for tassert.h */ 32: #include "tassert.h" 33: 34: static type *type_list = NULL; // free list of types 35: static param_t *param_list = NULL; // free list of params 36: 37: #ifdef DEBUG 38: static int type_num,type_max; /* gather statistics on # of types */ 39: #endif 40: 41: typep_t tstypes[TYMAX]; 42: typep_t tsptr2types[TYMAX]; 43: 44: typep_t tstrace,tsclib,tsjlib,tsdlib, 45: tslogical; 46: typep_t tspvoid,tspcvoid; 47: typep_t tsptrdiff, tssize; 48: 49: /******************************* 50: * Compute size of type in bytes. 51: */ 52: 53: targ_size_t type_size(type *t) 54: { targ_size_t s; 55: unsigned long u; 56: tym_t tyb; 57: 58: type_debug(t); 59: tyb = tybasic(t->Tty); 60: #ifdef DEBUG 61: if (tyb >= TYMAX) 62: /*type_print(t),*/ 63: dbg_printf("tyb = x%lx\n",tyb); 64: #endif 65: assert(tyb < TYMAX); 66: s = tysize[tyb]; 67: if (s == (targ_size_t) -1) 68: { 69: switch (tyb) 70: { 71: // in case program plays games with function pointers 72: case TYffunc: 73: case TYfpfunc: 74: #if TX86 75: case TYnfunc: /* in case program plays games with function pointers */ 76: case TYhfunc: 77: case TYnpfunc: 78: case TYnsfunc: 79: case TYfsfunc: 80: case TYf16func: 81: case TYifunc: 82: case TYjfunc: 83: #endif 84: #if SCPP 85: if (ANSI) 86: synerr(EM_unknown_size,"function"); /* size of function is not known */ 87: #endif 88: s = 1; 89: break; 90: case TYarray: 91: if (t->Tflags & TFsizeunknown) 92: { 93: #if SCPP 94: synerr(EM_unknown_size,"array"); /* size of array is unknown */ 95: #endif 96: t->Tflags &= ~TFsizeunknown; 97: } 98: if (t->Tflags & TFvla) 99: { 100: s = tysize[pointertype]; 101: break; 102: } 103: s = type_size(t->Tnext); 104: u = t->Tdim * (unsigned long) s; 105: #if TX86 && SCPP 106: type_chksize(u); 107: #endif 108: s = u; 109: break; 110: case TYstruct: 111: t = t->Ttag->Stype; /* find main instance */ 112: /* (for const struct X) */ 113: if (t->Tflags & TFsizeunknown) 114: { 115: #if SCPP 116: template_instantiate_forward(t->Ttag); 117: if (t->Tflags & TFsizeunknown) 118: synerr(EM_unknown_size,t->Tty & TYstruct ? prettyident(t->Ttag) : "struct"); 119: t->Tflags &= ~TFsizeunknown; 120: #endif 121: } 122: assert(t->Ttag); 123: s = t->Ttag->Sstruct->Sstructsize; 124: break; 125: #if SCPP 126: case TYenum: 127: if (t->Ttag->Senum->SEflags & SENforward) 128: synerr(EM_unknown_size, prettyident(t->Ttag)); 129: s = type_size(t->Tnext); 130: break; 131: #endif 132: case TYvoid: 133: #if SCPP && TARGET_WINDOS // GNUC allows it, so we will, too 134: synerr(EM_void_novalue); // voids have no value 135: #endif 136: s = 1; 137: break; 138: #if SCPP 139: case TYref: 140: case TYmemptr: 141: case TYvtshape: 142: s = tysize(tym_conv(t)); 143: break; 144: 145: case TYident: 146: synerr(EM_unknown_size, t->Tident); 147: s = 1; 148: break; 149: #endif 150: #if MARS 151: case TYref: 152: s = tysize(TYnptr); 153: break; 154: #endif 155: default: 156: #ifdef DEBUG 157: WRTYxx(t->Tty); 158: #endif 159: assert(0); 160: } 161: } 162: return s; 163: } 164: 165: /******************************** 166: * Return the size of a type for alignment purposes. 167: */ 168: 169: unsigned type_alignsize(type *t) 170: { targ_size_t sz; 171: 172: L1: 173: type_debug(t); 174: 175: sz = tyalignsize(t->Tty); 176: if (sz == (targ_size_t)-1) 177: { 178: switch (tybasic(t->Tty)) 179: { 180: case TYarray: 181: if (t->Tflags & TFsizeunknown) 182: goto err1; 183: t = t->Tnext; 184: goto L1; 185: case TYstruct: 186: t = t->Ttag->Stype; // find main instance 187: // (for const struct X) 188: if (t->Tflags & TFsizeunknown) 189: goto err1; 190: sz = t->Ttag->Sstruct->Salignsize; 191: if (sz > t->Ttag->Sstruct->Sstructalign) 192: sz = t->Ttag->Sstruct->Sstructalign; 193: break; 194: 195: case TYldouble: 196: assert(0); 197: 198: default: 199: err1: // let type_size() handle error messages 200: sz = type_size(t); 201: break; 202: } 203: } 204: 205: //printf("type_alignsize() = %d\n", sz); 206: return sz; 207: } 208: 209: /***************************** 210: * Compute the size of parameters for function call. 211: * Used for stdcall name mangling. 212: * Note that hidden parameters do not contribute to size. 213: */ 214: 215: targ_size_t type_paramsize(type *t) 216: { 217: targ_size_t sz = 0; 218: if (tyfunc(t->Tty)) 219: { 220: for (param_t *p = t->Tparamtypes; p; p = p->Pnext) 221: { 222: size_t n = type_size(p->Ptype); 223: n = align(REGSIZE,n); // align to REGSIZE boundary 224: sz += n; 225: } 226: } 227: return sz; 228: } 229: 230: /***************************** 231: * Create a type & initialize it. 232: * Input: 233: * ty = TYxxxx 234: * Returns: 235: * pointer to newly created type. 236: */ 237: 238: type *type_alloc(tym_t ty) 239: { type *t; 240: static type tzero; 241: 242: assert(tybasic(ty) != TYtemplate); 243: if (type_list) 244: { t = type_list; 245: type_list = t->Tnext; 246: } 247: else 248: t = (type *) mem_fmalloc(sizeof(type)); 249: tzero.Tty = ty; 250: *t = tzero; 251: #if SRCPOS_4TYPES 252: if (PARSER && config.fulltypes) 253: t->Tsrcpos = getlinnum(); 254: #endif 255: #ifdef DEBUG 256: t->id = IDtype; 257: type_num++; 258: if (type_num > type_max) 259: type_max = type_num; 260: #endif 261: //dbg_printf("type_alloc() = %p ",t); WRTYxx(t->Tty); dbg_printf("\n"); 262: //if (t == (type*)0xB6B744) *(char*)0=0; 263: return t; 264: } 265: 266: /************************************* 267: * Allocate a TYtemplate. 268: */ 269: 270: type *type_alloc_template(symbol *s) 271: { type *t; 272: 273: t = (type *) mem_fcalloc(sizeof(typetemp_t)); 274: t->Tty = TYtemplate; 275: if (s->Stemplate->TMprimary) 276: s = s->Stemplate->TMprimary; 277: ((typetemp_t *)t)->Tsym = s; 278: #if SRCPOS_4TYPES 279: if (PARSER && config.fulltypes) 280: t->Tsrcpos = getlinnum(); 281: #endif 282: #ifdef DEBUG 283: t->id = IDtype; 284: type_num++; 285: if (type_num > type_max) 286: type_max = type_num; 287: //dbg_printf("Alloc'ing template type %p ",t); WRTYxx(t->Tty); dbg_printf("\n"); 288: #endif 289: return t; 290: } 291: 292: /***************************** 293: * Fake a type & initialize it. 294: * Input: 295: * ty = TYxxxx 296: * Returns: 297: * pointer to newly created type. 298: */ 299: 300: type *type_fake(tym_t ty) 301: { type *t; 302: 303: #if MARS 304: assert(ty != TYstruct); 305: #endif 306: t = type_alloc(ty); 307: if (typtr(ty) || tyfunc(ty)) 308: { t->Tnext = type_alloc(TYvoid); /* fake with pointer to void */ 309: t->Tnext->Tcount = 1; 310: } 311: return t; 312: } 313: 314: /***************************** 315: * Allocate a type of ty with a Tnext of tn. 316: */ 317: 318: type *type_allocn(tym_t ty,type *tn) 319: { type *t; 320: 321: //printf("type_allocn(ty = x%x, tn = %p)\n", ty, tn); 322: assert(tn); 323: type_debug(tn); 324: t = type_alloc(ty); 325: t->Tnext = tn; 326: tn->Tcount++; 327: //printf("\tt = %p\n", t); 328: return t; 329: } 330: 331: /****************************** 332: * Allocate a TYmemptr type. 333: */ 334: 335: type *type_allocmemptr(Classsym *stag,type *tn) 336: { type *t; 337: 338: symbol_debug(stag); 339: assert(stag->Sclass == SCstruct || tybasic(stag->Stype->Tty) == TYident); 340: t = type_allocn(TYmemptr,tn); 341: t->Ttag = stag; 342: //printf("type_allocmemptr() = %p\n", t); 343: //type_print(t); 344: return t; 345: } 346: 347: /***************************** 348: * Free up data type. 349: */ 350: 351: void type_free(type *t) 352: { type *tn; 353: tym_t ty; 354: 355: while (t) 356: { 357: //dbg_printf("type_free(%p, Tcount = %d)\n", t, t->Tcount); 358: type_debug(t); 359: assert((int)t->Tcount != -1); 360: if (--t->Tcount) /* if usage count doesn't go to 0 */ 361: break; 362: ty = tybasic(t->Tty); 363: if (tyfunc(ty)) 364: { param_free(&t->Tparamtypes); 365: list_free(&t->Texcspec, (list_free_fp)type_free); 366: } 367: else if (ty == TYtemplate) 368: param_free(&t->Tparamtypes); 369: else if (ty == TYident) 370: MEM_PH_FREE(t->Tident); 371: else if (t->Tflags & TFvla && t->Tel) 372: el_free(t->Tel); 373: #if SCPP 374: else if (t->Talternate && typtr(ty)) 375: type_free(t->Talternate); 376: #endif 377: #if MARS 378: else if (t->Tkey && typtr(ty)) 379: type_free(t->Tkey); 380: #endif 381: #ifdef DEBUG 382: type_num--; 383: //dbg_printf("Free'ing type %p ",t); WRTYxx(t->Tty); dbg_printf("\n"); 384: t->id = 0; /* no longer a valid type */ 385: #endif 386: tn = t->Tnext; 387: t->Tnext = type_list; 388: type_list = t; /* link into free list */ 389: t = tn; 390: } 391: } 392: 393: #ifdef STATS 394: /* count number of free types available on type list */ 395: type_count_free() 396: { 397: type *t; 398: int count; 399: 400: for(t=type_list;t;t=t->Tnext) 401: count++; 402: dbg_printf("types on free list %d with max of %d\n",count,type_max); 403: } 404: #endif 405: 406: /********************************** 407: * Initialize type package. 408: */ 409: 410: STATIC type * __near type_allocbasic(tym_t ty) 411: { type *t; 412: 413: t = type_alloc(ty); 414: t->Tmangle = mTYman_c; 415: t->Tcount = 1; /* so it is not inadvertantly free'd */ 416: return t; 417: } 418: 419: void type_init() 420: { 421: tsbool = type_allocbasic(TYbool); 422: tswchar_t = type_allocbasic(TYwchar_t); 423: tsdchar = type_allocbasic(TYdchar); 424: tsvoid = type_allocbasic(TYvoid); 425: tsnullptr = type_allocbasic(TYnullptr); 426: tschar16 = type_allocbasic(TYchar16); 427: tsuchar = type_allocbasic(TYuchar); 428: tsschar = type_allocbasic(TYschar); 429: tschar = type_allocbasic(TYchar); 430: tsshort = type_allocbasic(TYshort); 431: tsushort = type_allocbasic(TYushort); 432: tsint = type_allocbasic(TYint); 433: tsuns = type_allocbasic(TYuint); 434: tslong = type_allocbasic(TYlong); 435: tsulong = type_allocbasic(TYulong); 436: tsllong = type_allocbasic(TYllong); 437: tsullong = type_allocbasic(TYullong); 438: tsfloat = type_allocbasic(TYfloat); 439: tsdouble = type_allocbasic(TYdouble); 440: tsreal64 = type_allocbasic(TYdouble_alias); 441: tsldouble = type_allocbasic(TYldouble); 442: tsifloat = type_allocbasic(TYifloat); 443: tsidouble = type_allocbasic(TYidouble); 444: tsildouble = type_allocbasic(TYildouble); 445: tscfloat = type_allocbasic(TYcfloat); 446: tscdouble = type_allocbasic(TYcdouble); 447: tscldouble = type_allocbasic(TYcldouble); 448: 449: if (I64) 450: { 451: TYptrdiff = TYllong; 452: TYsize = TYullong; 453: tsptrdiff = tsllong; 454: tssize = tsullong; 455: } 456: else 457: { 458: TYptrdiff = TYint; 459: TYsize = TYuint; 460: tsptrdiff = tsint; 461: tssize = tsuns; 462: } 463: 464: // Type of trace function 465: tstrace = type_fake(I16 ? TYffunc : TYnfunc); 466: tstrace->Tmangle = mTYman_c; 467: tstrace->Tcount++; 468: 469: #if TX86 470: chartype = (config.flags3 & CFG3ju) ? tsuchar : tschar; 471: 472: // Type of far library function 473: tsclib = type_fake(LARGECODE ? TYfpfunc : TYnpfunc); 474: tsclib->Tmangle = mTYman_c; 475: tsclib->Tcount++; 476: 477: tspvoid = type_allocn(pointertype,tsvoid); 478: tspvoid->Tmangle = mTYman_c; 479: tspvoid->Tcount++; 480: 481: // Type of far library function 482: tsjlib = type_fake(TYjfunc); 483: tsjlib->Tmangle = mTYman_c; 484: tsjlib->Tcount++; 485: 486: tsdlib = tsjlib; 487: 488: #if SCPP 489: tspcvoid = type_alloc(mTYconst | TYvoid); 490: tspcvoid = newpointer(tspcvoid); 491: tspcvoid->Tmangle = mTYman_c; 492: tspcvoid->Tcount++; 493: #endif 494: 495: // Type of logical expression 496: tslogical = (config.flags4 & CFG4bool) ? tsbool : tsint; 497: 498: for (int i = 0; i < TYMAX; i++) 499: { 500: if (tstypes[i]) 501: { tsptr2types[i] = type_allocn(pointertype,tstypes[i]); 502: tsptr2types[i]->Tcount++; 503: } 504: } 505: #else 506: chartype = tschar; /* default is signed chars */ 507: 508: type_list = NULL; 509: tsclib = type_fake( TYffunc ); 510: tsclib->Tmangle = mTYman_c; 511: tsclib->Tcount++; 512: #ifdef DEBUG 513: type_num = 0; 514: type_max = 0; 515: #endif /* DEBUG */ 516: #endif /* TX86 */ 517: } 518: 519: /********************************** 520: * Free type_list. 521: */ 522: 523: #if TERMCODE 524: void type_term() 525: { type *tn; 526: param_t *pn; 527: int i; 528: 529: for (i = 0; i < arraysize(tstypes); i++) 530: { type *t = tsptr2types[i]; 531: 532: if (t) 533: { assert(!(t->Tty & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 534: assert(!(t->Tflags)); 535: assert(!(t->Tmangle)); 536: type_free(t); 537: } 538: type_free(tstypes[i]); 539: } 540: 541: type_free(tsclib); 542: type_free(tspvoid); 543: type_free(tspcvoid); 544: type_free(tsjlib); 545: type_free(tstrace); 546: 547: while (type_list) 548: { tn = type_list->Tnext; 549: mem_ffree(type_list); 550: type_list = tn; 551: } 552: 553: while (param_list) 554: { pn = param_list->Pnext; 555: mem_ffree(param_list); 556: param_list = pn; 557: } 558: 559: #ifdef DEBUG 560: dbg_printf("Max # of types = %d\n",type_max); 561: if (type_num != 0) 562: dbg_printf("type_num = %d\n",type_num); 563: /* assert(type_num == 0);*/ 564: #endif 565: } 566: #endif // TERMCODE 567: 568: /******************************* 569: * Type type information. 570: */ 571: 572: /************************** 573: * Make copy of a type. 574: */ 575: 576: type *type_copy(type *t) 577: { type *tn; 578: param_t *p; 579: 580: type_debug(t); 581: if (tybasic(t->Tty) == TYtemplate) 582: { 583: tn = type_alloc_template(((typetemp_t *)t)->Tsym); 584: } 585: else 586: tn = type_alloc(t->Tty); 587: *tn = *t; 588: switch (tybasic(tn->Tty)) 589: { case TYtemplate: 590: ((typetemp_t *)tn)->Tsym = ((typetemp_t *)t)->Tsym; 591: goto L1; 592: 593: case TYident: 594: tn->Tident = (char *)MEM_PH_STRDUP(t->Tident); 595: break; 596: 597: case TYarray: 598: if (tn->Tflags & TFvla) 599: tn->Tel = el_copytree(tn->Tel); 600: break; 601: 602: default: 603: if (tyfunc(tn->Tty)) 604: { 605: L1: 606: tn->Tparamtypes = NULL; 607: for (p = t->Tparamtypes; p; p = p->Pnext) 608: { param_t *pn; 609: 610: pn = param_append_type(&tn->Tparamtypes,p->Ptype); 611: if (p->Pident) 612: { 613: pn->Pident = (char *)MEM_PH_STRDUP(p->Pident); 614: } 615: assert(!p->Pelem); 616: } 617: } 618: #if SCPP 619: else if (tn->Talternate && typtr(tn->Tty)) 620: tn->Talternate->Tcount++; 621: #endif 622: #if MARS 623: else if (tn->Tkey && typtr(tn->Tty)) 624: tn->Tkey->Tcount++; 625: #endif 626: break; 627: } 628: if (tn->Tnext) 629: { type_debug(tn->Tnext); 630: tn->Tnext->Tcount++; 631: } 632: tn->Tcount = 0; 633: return tn; 634: } 635: 636: /************************************ 637: */ 638: 639: #if SCPP 640: 641: elem *type_vla_fix(type **pt) 642: { 643: type *t; 644: elem *e = NULL; 645: 646: for (t = *pt; t; t = t->Tnext) 647: { 648: type_debug(t); 649: if (tybasic(t->Tty) == TYarray && t->Tflags & TFvla && t->Tel) 650: { symbol *s; 651: elem *ec; 652: 653: s = symbol_genauto(tsuns); 654: ec = el_var(s); 655: ec = el_bint(OPeq, tsuns, ec, t->Tel); 656: e = el_combine(e, ec); 657: t->Tel = el_var(s); 658: } 659: } 660: return e; 661: } 662: 663: #endif 664: 665: /**************************** 666: * Modify the tym_t field of a type. 667: */ 668: 669: type *type_setty(type **pt,long newty) 670: { type *t; 671: 672: t = *pt; 673: type_debug(t); 674: if ((tym_t)newty != t->Tty) 675: { if (t->Tcount > 1) /* if other people pointing at t */ 676: { type *tn; 677: 678: tn = type_copy(t); 679: tn->Tcount++; 680: type_free(t); 681: t = tn; 682: *pt = t; 683: } 684: t->Tty = newty; 685: } 686: return t; 687: } 688: 689: /****************************** 690: * Set type field of some object to t. 691: */ 692: 693: type *type_settype(type **pt, type *t) 694: { 695: if (t) 696: { type_debug(t); 697: t->Tcount++; 698: } 699: type_free(*pt); 700: return *pt = t; 701: } 702: 703: /**************************** 704: * Modify the Tmangle field of a type. 705: */ 706: 707: type *type_setmangle(type **pt,mangle_t mangle) 708: { type *t; 709: 710: t = *pt; 711: type_debug(t); 712: if (mangle != type_mangle(t)) 713: { 714: if (t->Tcount > 1) // if other people pointing at t 715: { type *tn; 716: 717: tn = type_copy(t); 718: tn->Tcount++; 719: type_free(t); 720: t = tn; 721: *pt = t; 722: } 723: t->Tmangle = mangle; 724: } 725: return t; 726: } 727: 728: /****************************** 729: * Set/clear const and volatile bits in *pt according to the settings 730: * in cv. 731: */ 732: 733: type *type_setcv(type **pt,tym_t cv) 734: { unsigned long ty; 735: 736: type_debug(*pt); 737: ty = (*pt)->Tty & ~(mTYconst | mTYvolatile | mTYimmutable | mTYshared); 738: return type_setty(pt,ty | (cv & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 739: } 740: 741: /***************************** 742: * Set dimension of array. 743: */ 744: 745: type *type_setdim(type **pt,targ_size_t dim) 746: { type *t = *pt; 747: 748: type_debug(t); 749: if (t->Tcount > 1) /* if other people pointing at t */ 750: { type *tn; 751: 752: tn = type_copy(t); 753: tn->Tcount++; 754: type_free(t); 755: t = tn; 756: } 757: t->Tflags &= ~TFsizeunknown; /* we have determined its size */ 758: t->Tdim = dim; /* index of array */ 759: return *pt = t; 760: } 761: 762: 763: /***************************** 764: * Create a 'dependent' version of type t. 765: */ 766: 767: type *type_setdependent(type *t) 768: { 769: type_debug(t); 770: if (t->Tcount > 0 && /* if other people pointing at t */ 771: !(t->Tflags & TFdependent)) 772: { 773: t = type_copy(t); 774: } 775: t->Tflags |= TFdependent; 776: return t; 777: } 778: 779: /************************************ 780: * Determine if type t is a dependent type. 781: */ 782: 783: int type_isdependent(type *t) 784: { 785: Symbol *stempl; 786: type *tstart; 787: 788: //printf("type_isdependent(%p)\n", t); 789: //type_print(t); 790: for (tstart = t; t; t = t->Tnext) 791: { 792: type_debug(t); 793: if (t->Tflags & TFdependent) 794: goto Lisdependent; 795: if (tyfunc(t->Tty) || tybasic(t->Tty) == TYtemplate) 796: { 797: for (param_t *p = t->Tparamtypes; p; p = p->Pnext) 798: { 799: if (p->Ptype && type_isdependent(p->Ptype)) 800: goto Lisdependent; 801: if (p->Pelem && el_isdependent(p->Pelem)) 802: goto Lisdependent; 803: } 804: } 805: else if (type_struct(t) && 806: (stempl = t->Ttag->Sstruct->Stempsym) != NULL) 807: { 808: for (param_t *p = t->Ttag->Sstruct->Sarglist; p; p = p->Pnext) 809: { 810: if (p->Ptype && type_isdependent(p->Ptype)) 811: goto Lisdependent; 812: if (p->Pelem && el_isdependent(p->Pelem)) 813: goto Lisdependent; 814: } 815: } 816: } 817: //printf("\tis not dependent\n"); 818: return 0; 819: 820: Lisdependent: 821: //printf("\tis dependent\n"); 822: // Dependence on a dependent type makes this type dependent as well 823: tstart->Tflags |= TFdependent; 824: return 1; 825: } 826: 827: 828: /******************************* 829: * Recursively check if type u is embedded in type t. 830: * Returns: 831: * != 0 if embedded 832: */ 833: 834: int type_embed(type *t,type *u) 835: { param_t *p; 836: 837: for (; t; t = t->Tnext) 838: { 839: type_debug(t); 840: if (t == u) 841: return 1; 842: if (tyfunc(t->Tty)) 843: { 844: for (p = t->Tparamtypes; p; p = p->Pnext) 845: if (type_embed(p->Ptype,u)) 846: return 1; 847: } 848: } 849: return 0; 850: } 851: 852: 853: /*********************************** 854: * Determine if type is a VLA. 855: */ 856: 857: int type_isvla(type *t) 858: { 859: while (t) 860: { 861: if (tybasic(t->Tty) != TYarray) 862: break; 863: if (t->Tflags & TFvla) 864: return 1; 865: t = t->Tnext; 866: } 867: return 0; 868: } 869: 870: /************************************* 871: * Determine if type can be passed in a register. 872: */ 873: 874: int type_jparam(type *t) 875: { 876: targ_size_t sz; 877: type_debug(t); 878: return tyjparam(t->Tty) || 879: ((tybasic(t->Tty) == TYstruct || tybasic(t->Tty) == TYarray) && 880: (sz = type_size(t)) <= NPTRSIZE &&warning C4018: '<=' : signed/unsigned mismatch881: (sz == 1 || sz == 2 || sz == 4 || sz == 8)); 882: } 883: 884: 885: /********************************** 886: * Pretty-print a type. 887: */ 888: 889: #ifdef DEBUG 890: 891: void type_print(type *t) 892: { 893: type_debug(t); 894: dbg_printf("Tty="); WRTYxx(t->Tty); 895: dbg_printf(" Tmangle=%d",t->Tmangle); 896: dbg_printf(" Tflags=x%x",t->Tflags); 897: dbg_printf(" Tcount=%d",t->Tcount); 898: if (!(t->Tflags & TFsizeunknown) && 899: tybasic(t->Tty) != TYvoid && 900: tybasic(t->Tty) != TYident && 901: tybasic(t->Tty) != TYmfunc && 902: tybasic(t->Tty) != TYarray && 903: tybasic(t->Tty) != TYtemplate) 904: dbg_printf(" Tsize=%ld",type_size(t)); 905: dbg_printf(" Tnext=%p",t->Tnext); 906: switch (tybasic(t->Tty)) 907: { case TYstruct: 908: case TYmemptr: 909: dbg_printf(" Ttag=%p,'%s'",t->Ttag,t->Ttag->Sident); 910: //dbg_printf(" Sfldlst=%p",t->Ttag->Sstruct->Sfldlst); 911: break; 912: case TYarray: 913: dbg_printf(" Tdim=%ld",t->Tdim); 914: break; 915: case TYident: 916: dbg_printf(" Tident='%s'",t->Tident); 917: break; 918: case TYtemplate: 919: dbg_printf(" Tsym='%s'",((typetemp_t *)t)->Tsym->Sident); 920: { param_t *p; 921: int i; 922: 923: i = 1; 924: for (p = t->Tparamtypes; p; p = p->Pnext) 925: { dbg_printf("\nTP%d (%p): ",i++,p); 926: fflush(stdout); 927: 928: dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext); 929: param_debug(p); 930: if (p->Pident) 931: printf("'%s' ", p->Pident); 932: if (p->Ptype) 933: type_print(p->Ptype); 934: if (p->Pelem) 935: elem_print(p->Pelem); 936: } 937: } 938: break; 939: default: 940: if (tyfunc(t->Tty)) 941: { param_t *p; 942: int i; 943: 944: i = 1; 945: for (p = t->Tparamtypes; p; p = p->Pnext) 946: { dbg_printf("\nP%d (%p): ",i++,p); 947: fflush(stdout); 948: 949: dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p->Pident,p->Ptype,p->Pelem,p->Pnext); 950: param_debug(p); 951: if (p->Pident) 952: printf("'%s' ", p->Pident); 953: type_print(p->Ptype); 954: } 955: } 956: break; 957: } 958: dbg_printf("\n"); 959: if (t->Tnext) type_print(t->Tnext); 960: } 961: 962: /******************************* 963: * Pretty-print a param_t 964: */ 965: 966: void param_t::print() 967: { 968: dbg_printf("Pident=%p,Ptype=%p,Pelem=%p,Psym=%p,Pnext=%p\n",Pident,Ptype,Pelem,Psym,Pnext); 969: if (Pident) 970: dbg_printf("\tPident = '%s'\n", Pident); 971: if (Ptype) 972: { dbg_printf("\tPtype =\n"); 973: type_print(Ptype); 974: } 975: if (Pelem) 976: { dbg_printf("\tPelem =\n"); 977: elem_print(Pelem); 978: } 979: if (Pdeftype) 980: { dbg_printf("\tPdeftype =\n"); 981: type_print(Pdeftype); 982: } 983: if (Psym) 984: { dbg_printf("\tPsym = '%s'\n", Psym->Sident); 985: } 986: if (Pptpl) 987: { dbg_printf("\tPptpl = %p\n", Pptpl); 988: } 989: } 990: 991: void param_t::print_list() 992: { 993: for (param_t *p = this; p; p = p->Pnext) 994: p->print(); 995: } 996: 997: #endif /* DEBUG */ 998: 999: /********************************** 1000: * Hydrate a type. 1001: */ 1002: 1003: #if HYDRATE 1004: void type_hydrate(type **pt) 1005: { 1006: type *t; 1007: 1008: assert(pt); 1009: while (isdehydrated(*pt)) 1010: { 1011: t = (type *) ph_hydrate(pt); 1012: type_debug(t); 1013: switch (tybasic(t->Tty)) 1014: { 1015: case TYstruct: 1016: case TYenum: 1017: case TYmemptr: 1018: case TYvtshape: 1019: // Cannot assume symbol is hydrated, because entire HX file 1020: // may not have been hydrated. 1021: Classsym_hydrate(&t->Ttag); 1022: symbol_debug(t->Ttag); 1023: break; 1024: case TYident: 1025: ph_hydrate(&t->Tident); 1026: break; 1027: case TYtemplate: 1028: symbol_hydrate(&((typetemp_t *)t)->Tsym); 1029: param_hydrate(&t->Tparamtypes); 1030: break; 1031: case TYarray: 1032: if (t->Tflags & TFvla) 1033: el_hydrate(&t->Tel); 1034: break; 1035: default: 1036: if (tyfunc(t->Tty)) 1037: { param_hydrate(&t->Tparamtypes); 1038: list_hydrate(&t->Texcspec, (list_free_fp)type_hydrate); 1039: } 1040: #if SCPP 1041: else if (t->Talternate && typtr(t->Tty)) 1042: type_hydrate(&t->Talternate); 1043: #endif 1044: #if MARS 1045: else if (t->Tkey && typtr(t->Tty)) 1046: type_hydrate(&t->Tkey); 1047: #endif 1048: break; 1049: } 1050: pt = &t->Tnext; 1051: } 1052: } 1053: #endif 1054: 1055: /********************************** 1056: * Dehydrate a type. 1057: */ 1058: 1059: #if DEHYDRATE 1060: void type_dehydrate(type **pt) 1061: { 1062: type *t; 1063: 1064: while ((t = *pt) != NULL && !isdehydrated(t)) 1065: { 1066: ph_dehydrate(pt); 1067: #if DEBUG_XSYMGEN 1068: /* don't dehydrate types in HEAD when creating XSYM */ 1069: if (xsym_gen && (t->Tflags & TFhydrated)) 1070: return; 1071: #endif 1072: type_debug(t); 1073: switch (tybasic(t->Tty)) 1074: { 1075: case TYstruct: 1076: case TYenum: 1077: case TYmemptr: 1078: case TYvtshape: 1079: Classsym_dehydrate(&t->Ttag); 1080: break; 1081: case TYident: 1082: ph_dehydrate(&t->Tident); 1083: break; 1084: case TYtemplate: 1085: symbol_dehydrate(&((typetemp_t *)t)->Tsym); 1086: param_dehydrate(&t->Tparamtypes); 1087: break; 1088: case TYarray: 1089: if (t->Tflags & TFvla) 1090: el_dehydrate(&t->Tel); 1091: break; 1092: default: 1093: if (tyfunc(t->Tty)) 1094: { param_dehydrate(&t->Tparamtypes); 1095: list_dehydrate(&t->Texcspec, (list_free_fp)type_dehydrate); 1096: } 1097: #if SCPP 1098: else if (t->Talternate && typtr(t->Tty)) 1099: type_dehydrate(&t->Talternate); 1100: #endif 1101: #if MARS 1102: else if (t->Tkey && typtr(t->Tty)) 1103: type_dehydrate(&t->Tkey); 1104: #endif 1105: break; 1106: } 1107: pt = &t->Tnext; 1108: } 1109: } 1110: #endif 1111: 1112: /**************************** 1113: * Allocate a param_t. 1114: */ 1115: 1116: param_t *param_calloc() 1117: { 1118: static param_t pzero; 1119: param_t *p; 1120: 1121: #if !TX86 1122: debug_assert(PARSER); 1123: #endif 1124: if (param_list) 1125: { 1126: p = param_list; 1127: param_list = p->Pnext; 1128: } 1129: else 1130: { 1131: p = (param_t *) mem_fmalloc(sizeof(param_t)); 1132: } 1133: *p = pzero; 1134: #ifdef DEBUG 1135: p->id = IDparam; 1136: #endif 1137: return p; 1138: } 1139: 1140: /*************************** 1141: * Allocate a param_t of type t, and append it to parameter list. 1142: */ 1143: 1144: param_t *param_append_type(param_t **pp,type *t) 1145: { param_t *p; 1146: 1147: p = param_calloc(); 1148: while (*pp) 1149: { param_debug(*pp); 1150: pp = &((*pp)->Pnext); /* find end of list */ 1151: } 1152: *pp = p; /* append p to list */ 1153: type_debug(t); 1154: p->Ptype = t; 1155: t->Tcount++; 1156: return p; 1157: } 1158: 1159: /************************ 1160: * Version of param_free() suitable for list_free(). 1161: */ 1162: 1163: void param_free_l(param_t *p) 1164: { 1165: param_free(&p); 1166: } 1167: 1168: /*********************** 1169: * Free parameter list. 1170: * Output: 1171: * paramlst = NULL 1172: */ 1173: 1174: void param_free(param_t **pparamlst) 1175: { param_t *p,*pn; 1176: 1177: #if !TX86 1178: debug_assert(PARSER); 1179: #endif 1180: for (p = *pparamlst; p; p = pn) 1181: { param_debug(p); 1182: pn = p->Pnext; 1183: type_free(p->Ptype); 1184: mem_free(p->Pident); 1185: el_free(p->Pelem); 1186: type_free(p->Pdeftype); 1187: if (p->Pptpl) 1188: param_free(&p->Pptpl); 1189: #ifdef DEBUG 1190: p->id = 0; 1191: #endif 1192: p->Pnext = param_list; 1193: param_list = p; 1194: } 1195: *pparamlst = NULL; 1196: } 1197: 1198: /*********************************** 1199: * Compute number of parameters 1200: */ 1201: 1202: unsigned param_t::length() 1203: { 1204: unsigned nparams = 0; 1205: param_t *p; 1206: 1207: for (p = this; p; p = p->Pnext) 1208: nparams++; 1209: return nparams; 1210: } 1211: 1212: /************************************* 1213: * Create template-argument-list blank from 1214: * template-parameter-list 1215: * Input: 1216: * ptali initial template-argument-list 1217: */ 1218: 1219: param_t *param_t::createTal(param_t *ptali) 1220: { 1221: #if SCPP 1222: param_t *ptalistart = ptali; 1223: #endif 1224: param_t *ptal = NULL; 1225: param_t **pp = &ptal; 1226: param_t *p; 1227: 1228: for (p = this; p; p = p->Pnext) 1229: { 1230: *pp = param_calloc(); 1231: if (p->Pident) 1232: { 1233: // Should find a way to just point rather than dup 1234: (*pp)->Pident = (char *)MEM_PH_STRDUP(p->Pident); 1235: } 1236: if (ptali) 1237: { 1238: if (ptali->Ptype) 1239: { (*pp)->Ptype = ptali->Ptype; 1240: (*pp)->Ptype->Tcount++; 1241: } 1242: if (ptali->Pelem) 1243: { 1244: elem *e = el_copytree(ptali->Pelem); 1245: #if SCPP 1246: if (p->Ptype) 1247: { type *t = p->Ptype; 1248: t = template_tyident(t, ptalistart, this, 1); 1249: e = poptelem3(typechk(e, t)); 1250: type_free(t); 1251: } 1252: #endif 1253: (*pp)->Pelem = e; 1254: } 1255: (*pp)->Psym = ptali->Psym; 1256: (*pp)->Pflags = ptali->Pflags; 1257: assert(!ptali->Pptpl); 1258: ptali = ptali->Pnext; 1259: } 1260: pp = &(*pp)->Pnext; 1261: } 1262: return ptal; 1263: } 1264: 1265: /********************************** 1266: * Look for Pident matching id 1267: */ 1268: 1269: param_t *param_t::search(char *id) 1270: { param_t *p; 1271: 1272: for (p = this; p; p = p->Pnext) 1273: { 1274: if (p->Pident && strcmp(p->Pident, id) == 0) 1275: break; 1276: } 1277: return p; 1278: } 1279: 1280: /********************************** 1281: * Look for Pident matching id 1282: */ 1283: 1284: int param_t::searchn(char *id) 1285: { param_t *p; 1286: int n = 0; 1287: 1288: for (p = this; p; p = p->Pnext) 1289: { 1290: if (p->Pident && strcmp(p->Pident, id) == 0) 1291: return n; 1292: n++; 1293: } 1294: return -1; 1295: } 1296: 1297: /************************************* 1298: * Search for member, create symbol as needed. 1299: * Used for symbol tables for VLA's such as: 1300: * void func(int n, int a[n]); 1301: */ 1302: 1303: symbol *param_search(const char *name, param_t **pp) 1304: { symbol *s = NULL; 1305: param_t *p; 1306: 1307: p = (*pp)->search((char *)name); 1308: if (p) 1309: { 1310: s = p->Psym; 1311: if (!s) 1312: { 1313: s = symbol_calloc(p->Pident); 1314: s->Sclass = SCparameter; 1315: s->Stype = p->Ptype; 1316: s->Stype->Tcount++; 1317: #if SOURCE_4PARAMS 1318: s->Ssrcpos = p->Psrcpos; 1319: #endif 1320: p->Psym = s; 1321: } 1322: } 1323: return s; 1324: } 1325: 1326: /********************************** 1327: * Hydrate/dehydrate a type. 1328: */ 1329: 1330: #if HYDRATE 1331: void param_hydrate(param_t **pp) 1332: { 1333: param_t *p; 1334: 1335: assert(pp); 1336: if (isdehydrated(*pp)) 1337: { while (*pp) 1338: { assert(isdehydrated(*pp)); 1339: p = (param_t *) ph_hydrate(pp); 1340: #if SOURCE_4PARAMS 1341: p->Psrcpos.Sfilnum += File_Hydrate_Num; /* file number relative header build */ 1342: #endif 1343: param_debug(p); 1344: 1345: type_hydrate(&p->Ptype); 1346: if (p->Ptype) 1347: type_debug(p->Ptype); 1348: ph_hydrate(&p->Pident); 1349: if (CPP) 1350: { 1351: el_hydrate(&p->Pelem); 1352: if (p->Pelem) 1353: elem_debug(p->Pelem); 1354: type_hydrate(&p->Pdeftype); 1355: if (p->Pptpl) 1356: param_hydrate(&p->Pptpl); 1357: if (p->Psym) 1358: symbol_hydrate(&p->Psym); 1359: if (p->PelemToken) 1360: token_hydrate(&p->PelemToken); 1361: } 1362: 1363: pp = &p->Pnext; 1364: } 1365: } 1366: } 1367: #endif 1368: 1369: #if DEHYDRATE 1370: void param_dehydrate(param_t **pp) 1371: { 1372: param_t *p; 1373: 1374: assert(pp); 1375: while ((p = *pp) != NULL && !isdehydrated(p)) 1376: { param_debug(p); 1377: 1378: ph_dehydrate(pp); 1379: if (p->Ptype && !isdehydrated(p->Ptype)) 1380: type_debug(p->Ptype); 1381: type_dehydrate(&p->Ptype); 1382: ph_dehydrate(&p->Pident); 1383: if (CPP) 1384: { 1385: el_dehydrate(&p->Pelem); 1386: type_dehydrate(&p->Pdeftype); 1387: if (p->Pptpl) 1388: param_dehydrate(&p->Pptpl); 1389: if (p->Psym) 1390: symbol_dehydrate(&p->Psym); 1391: if (p->PelemToken) 1392: token_dehydrate(&p->PelemToken); 1393: } 1394: pp = &p->Pnext; 1395: } 1396: } 1397: #endif 1398: 1399: #if MARS 1400: 1401: int typematch(type *t1, type *t2, int relax); 1402: 1403: // Return TRUE if type lists match. 1404: static int paramlstmatch(param_t *p1,param_t *p2) 1405: { 1406: return p1 == p2 || 1407: p1 && p2 && typematch(p1->Ptype,p2->Ptype,0) && 1408: paramlstmatch(p1->Pnext,p2->Pnext) 1409: ; 1410: } 1411: 1412: /************************************************* 1413: * A cheap version of exp2.typematch() and exp2.paramlstmatch(), 1414: * so that we can get cpp_mangle() to work for MARS. 1415: * It's less complex because it doesn't do templates and 1416: * can rely on strict typechecking. 1417: * Returns: 1418: * !=0 if types match. 1419: */ 1420: 1421: int typematch(type *t1,type *t2,int relax) 1422: { tym_t t1ty, t2ty; 1423: tym_t tym; 1424: 1425: tym = ~(mTYimport | mTYnaked); 1426: 1427: return t1 == t2 || 1428: t1 && t2 && 1429: 1430: ( 1431: /* ignore name mangling */ 1432: (t1ty = (t1->Tty & tym)) == (t2ty = (t2->Tty & tym)) 1433: ) 1434: && 1435: 1436: (tybasic(t1ty) != TYarray || t1->Tdim == t2->Tdim || 1437: t1->Tflags & TFsizeunknown || t2->Tflags & TFsizeunknown) 1438: && 1439: 1440: (tybasic(t1ty) != TYstruct 1441: && tybasic(t1ty) != TYenum 1442: && tybasic(t1ty) != TYmemptr 1443: || t1->Ttag == t2->Ttag) 1444: && 1445: 1446: typematch(t1->Tnext,t2->Tnext, 0) 1447: && 1448: 1449: (!tyfunc(t1ty) || 1450: ((t1->Tflags & TFfixed) == (t2->Tflags & TFfixed) && 1451: paramlstmatch(t1->Tparamtypes,t2->Tparamtypes) )) 1452: ; 1453: } 1454: 1455: #endif 1456: 1457: #endif /* !SPP */ 1458: