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 mismatch
881: (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: