1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1985-1998 by Symantec 6 * Copyright (C) 2000-2020 by The D Language Foundation, All Rights Reserved 7 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 8 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 9 * Source: https://github.com/dlang/dmd/blob/master/src/dmd/backend/dtype.d 10 */ 11 12 module dmd.backend.dtype; 13 14 version (SCPP) 15 { 16 version = COMPILE; 17 version = SCPP_HTOD; 18 } 19 version (HTOD) 20 { 21 version = COMPILE; 22 version = SCPP_HTOD; 23 } 24 version (MARS) 25 version = COMPILE; 26 27 28 version (COMPILE) 29 { 30 import core.stdc.stdio; 31 import core.stdc.stdlib; 32 import core.stdc..string; 33 34 import dmd.backend.cdef; 35 import dmd.backend.cc; 36 import dmd.backend.dlist; 37 import dmd.backend.el; 38 import dmd.backend.global; 39 import dmd.backend.mem; 40 import dmd.backend.oper; 41 import dmd.backend.ty; 42 import dmd.backend.type; 43 44 version (SCPP_HTOD) 45 { 46 import dtoken; 47 import msgs2; 48 import parser; 49 import precomp; 50 } 51 52 extern (C++): 53 54 nothrow: 55 56 alias MEM_PH_MALLOC = mem_malloc; 57 alias MEM_PH_CALLOC = mem_calloc; 58 alias MEM_PH_FREE = mem_free; 59 alias MEM_PH_STRDUP = mem_strdup; 60 alias MEM_PARF_MALLOC = mem_malloc; 61 alias MEM_PARF_CALLOC = mem_calloc; 62 alias MEM_PARF_REALLOC = mem_realloc; 63 alias MEM_PARF_FREE = mem_free; 64 alias MEM_PARF_STRDUP = mem_strdup; 65 66 version (SCPP_HTOD) 67 struct_t* struct_calloc(); 68 else 69 struct_t* struct_calloc() { return cast(struct_t*) mem_calloc(struct_t.sizeof); } 70 71 int REGSIZE(); 72 73 private __gshared 74 { 75 type *type_list; // free list of types 76 param_t *param_list; // free list of params 77 78 int type_num,type_max; /* gather statistics on # of types */ 79 } 80 81 __gshared 82 { 83 type*[TYMAX] tstypes; 84 type*[TYMAX] tsptr2types; 85 86 type* tstrace,tsclib,tsjlib,tsdlib, 87 tslogical; 88 type* tspvoid,tspcvoid; 89 type* tsptrdiff, tssize; 90 } 91 92 /******************************* 93 * Compute size of type in bytes. 94 * Mark size as known after error message if it is not known. 95 * Instantiate templates as needed to compute size. 96 * Params: 97 * t = type 98 * Returns: 99 * size 100 */ 101 102 version (SCPP_HTOD) 103 { 104 targ_size_t type_size(type* t) 105 { 106 switch (tybasic(t.Tty)) 107 { 108 case TYarray: 109 if (t.Tflags & TFsizeunknown) 110 { 111 synerr(EM_unknown_size,"array".ptr); /* size of array is unknown */ 112 t.Tflags &= ~TFsizeunknown; 113 } 114 type_size(t.Tnext); 115 break; 116 117 case TYstruct: 118 auto ts = t.Ttag.Stype; // find main instance 119 // (for const struct X) 120 if (ts.Tflags & TFsizeunknown) 121 { 122 template_instantiate_forward(ts.Ttag); 123 if (ts.Tflags & TFsizeunknown) 124 synerr(EM_unknown_size,ts.Tty & TYstruct ? prettyident(ts.Ttag) : "struct"); 125 ts.Tflags &= ~TFsizeunknown; 126 } 127 break; 128 129 case TYenum: 130 if (t.Ttag.Senum.SEflags & SENforward) 131 synerr(EM_unknown_size, prettyident(t.Ttag)); 132 type_size(t.Tnext); 133 break; 134 135 default: 136 break; 137 } 138 return type_size(cast(const)t); 139 } 140 } 141 142 /*********************** 143 * Compute size of type in bytes. 144 * Params: 145 * t = type 146 * Returns: 147 * size 148 */ 149 targ_size_t type_size(const type *t) 150 { targ_size_t s; 151 tym_t tyb; 152 153 type_debug(t); 154 tyb = tybasic(t.Tty); 155 156 debug if (tyb >= TYMAX) 157 /*type_print(t),*/ 158 printf("tyb = x%x\n", tyb); 159 160 assert(tyb < TYMAX); 161 s = _tysize[tyb]; 162 if (s == cast(targ_size_t) -1) 163 { 164 switch (tyb) 165 { 166 // in case program plays games with function pointers 167 case TYffunc: 168 case TYfpfunc: 169 case TYfsfunc: 170 case TYf16func: 171 case TYhfunc: 172 case TYnfunc: /* in case program plays games with function pointers */ 173 case TYnpfunc: 174 case TYnsfunc: 175 case TYifunc: 176 case TYjfunc: 177 version (SCPP_HTOD) 178 { 179 case TYmfunc: 180 if (config.ansi_c) 181 synerr(EM_unknown_size,"function".ptr); /* size of function is not known */ 182 } 183 s = 1; 184 break; 185 case TYarray: 186 { 187 if (t.Tflags & TFsizeunknown) 188 { 189 version (SCPP_HTOD) 190 { 191 synerr(EM_unknown_size,"array".ptr); /* size of array is unknown */ 192 } 193 } 194 if (t.Tflags & TFvla) 195 { 196 s = _tysize[pointertype]; 197 break; 198 } 199 s = type_size(t.Tnext); 200 uint u = cast(uint)t.Tdim * cast(uint) s; 201 version (SCPP_HTOD) 202 { 203 type_chksize(u); 204 } 205 else version (MARS) 206 { 207 if (t.Tdim && ((u / t.Tdim) != s || cast(int)u < 0)) 208 assert(0); // overflow should have been detected in front end 209 } 210 else 211 { 212 static assert(0); 213 } 214 s = u; 215 break; 216 } 217 case TYstruct: 218 { 219 auto ts = t.Ttag.Stype; // find main instance 220 // (for const struct X) 221 assert(ts.Ttag); 222 s = ts.Ttag.Sstruct.Sstructsize; 223 break; 224 } 225 version (SCPP_HTOD) 226 { 227 case TYenum: 228 if (t.Ttag.Senum.SEflags & SENforward) 229 synerr(EM_unknown_size, prettyident(cast(Symbol*)t.Ttag)); 230 s = type_size(t.Tnext); 231 break; 232 } 233 case TYvoid: 234 version (SCPP_HTOD) static if (TARGET_WINDOS) // GNUC allows it, so we will, too 235 { 236 synerr(EM_void_novalue); // voids have no value 237 } 238 s = 1; 239 break; 240 241 case TYref: 242 version (MARS) 243 { 244 s = tysize(TYnptr); 245 break; 246 } 247 version (SCPP_HTOD) 248 { 249 case TYmemptr: 250 case TYvtshape: 251 s = tysize(tym_conv(t)); 252 break; 253 254 case TYident: 255 synerr(EM_unknown_size, t.Tident); 256 s = 1; 257 break; 258 } 259 260 default: 261 debug WRTYxx(t.Tty); 262 assert(0); 263 } 264 } 265 return s; 266 } 267 268 /******************************** 269 * Return the size of a type for alignment purposes. 270 */ 271 272 uint type_alignsize(type *t) 273 { targ_size_t sz; 274 275 L1: 276 type_debug(t); 277 278 sz = tyalignsize(t.Tty); 279 if (sz == cast(targ_size_t)-1) 280 { 281 switch (tybasic(t.Tty)) 282 { 283 case TYarray: 284 if (t.Tflags & TFsizeunknown) 285 goto err1; 286 t = t.Tnext; 287 goto L1; 288 case TYstruct: 289 t = t.Ttag.Stype; // find main instance 290 // (for const struct X) 291 if (t.Tflags & TFsizeunknown) 292 goto err1; 293 sz = t.Ttag.Sstruct.Salignsize; 294 if (sz > t.Ttag.Sstruct.Sstructalign + 1) 295 sz = t.Ttag.Sstruct.Sstructalign + 1; 296 break; 297 298 case TYldouble: 299 assert(0); 300 301 default: 302 err1: // let type_size() handle error messages 303 sz = type_size(t); 304 break; 305 } 306 } 307 308 //printf("type_alignsize() = %d\n", sz); 309 return cast(uint)sz; 310 } 311 312 /*********************************** 313 * Compute special zero sized struct. 314 * Params: 315 * t = type of parameter 316 * tyf = function type 317 * Returns: 318 * true if it is 319 */ 320 bool type_zeroSize(type *t, tym_t tyf) 321 { 322 if (tyf != TYjfunc && config.exe & (EX_FREEBSD | EX_OSX)) 323 { 324 /* Use clang convention for 0 size structs 325 */ 326 if (t && tybasic(t.Tty) == TYstruct) 327 { 328 type *ts = t.Ttag.Stype; // find main instance 329 // (for const struct X) 330 if (ts.Tflags & TFsizeunknown) 331 { 332 version (SCPP_HTOD) 333 { 334 template_instantiate_forward(ts.Ttag); 335 if (ts.Tflags & TFsizeunknown) 336 synerr(EM_unknown_size,ts.Tty & TYstruct ? prettyident(ts.Ttag) : "struct"); 337 ts.Tflags &= ~TFsizeunknown; 338 } 339 } 340 if (ts.Ttag.Sstruct.Sflags & STR0size) 341 //{ printf("0size\n"); type_print(t); *(char*)0=0; 342 return true; 343 //} 344 } 345 } 346 return false; 347 } 348 349 /********************************* 350 * Compute the size of a single parameter. 351 * Params: 352 * t = type of parameter 353 * tyf = function type 354 * Returns: 355 * size in bytes 356 */ 357 uint type_parameterSize(type *t, tym_t tyf) 358 { 359 if (type_zeroSize(t, tyf)) 360 return 0; 361 return cast(uint)type_size(t); 362 } 363 364 /***************************** 365 * Compute the total size of parameters for function call. 366 * Used for stdcall name mangling. 367 * Note that hidden parameters do not contribute to size. 368 * Params: 369 * t = function type 370 * Returns: 371 * total stack usage in bytes 372 */ 373 374 uint type_paramsize(type *t) 375 { 376 targ_size_t sz = 0; 377 if (tyfunc(t.Tty)) 378 { 379 for (param_t *p = t.Tparamtypes; p; p = p.Pnext) 380 { 381 const size_t n = type_parameterSize(p.Ptype, tybasic(t.Tty)); 382 sz += _align(REGSIZE,n); // align to REGSIZE boundary 383 } 384 } 385 return cast(uint)sz; 386 } 387 388 /***************************** 389 * Create a type & initialize it. 390 * Input: 391 * ty = TYxxxx 392 * Returns: 393 * pointer to newly created type. 394 */ 395 396 type *type_alloc(tym_t ty) 397 { type *t; 398 __gshared type tzero; 399 400 assert(tybasic(ty) != TYtemplate); 401 if (type_list) 402 { t = type_list; 403 type_list = t.Tnext; 404 } 405 else 406 t = cast(type *) mem_fmalloc(type.sizeof); 407 tzero.Tty = ty; 408 *t = tzero; 409 version (SRCPOS_4TYPES) 410 { 411 if (PARSER && config.fulltypes) 412 t.Tsrcpos = getlinnum(); 413 } 414 debug 415 { 416 t.id = type.IDtype; 417 type_num++; 418 if (type_num > type_max) 419 type_max = type_num; 420 } 421 //printf("type_alloc() = %p ",t); WRTYxx(t.Tty); printf("\n"); 422 //if (t == (type*)0xB6B744) *(char*)0=0; 423 return t; 424 } 425 426 /************************************* 427 * Allocate a TYtemplate. 428 */ 429 430 version (SCPP_HTOD) 431 { 432 type *type_alloc_template(Symbol *s) 433 { type *t; 434 435 t = cast(type *) mem_fmalloc(typetemp_t.sizeof); 436 memset(t, 0, typetemp_t.sizeof); 437 t.Tty = TYtemplate; 438 if (s.Stemplate.TMprimary) 439 s = s.Stemplate.TMprimary; 440 (cast(typetemp_t *)t).Tsym = s; 441 version (SRCPOS_4TYPES) 442 { 443 if (PARSER && config.fulltypes) 444 t.Tsrcpos = getlinnum(); 445 } 446 debug 447 { 448 t.id = type.IDtype; 449 type_num++; 450 if (type_num > type_max) 451 type_max = type_num; 452 //printf("Alloc'ing template type %p ",t); WRTYxx(t.Tty); printf("\n"); 453 } 454 return t; 455 } 456 } 457 458 /***************************** 459 * Fake a type & initialize it. 460 * Input: 461 * ty = TYxxxx 462 * Returns: 463 * pointer to newly created type. 464 */ 465 466 type *type_fake(tym_t ty) 467 { type *t; 468 469 version (MARS) 470 assert(ty != TYstruct); 471 472 t = type_alloc(ty); 473 if (typtr(ty) || tyfunc(ty)) 474 { t.Tnext = type_alloc(TYvoid); /* fake with pointer to void */ 475 t.Tnext.Tcount = 1; 476 } 477 return t; 478 } 479 480 /***************************** 481 * Allocate a type of ty with a Tnext of tn. 482 */ 483 484 type *type_allocn(tym_t ty,type *tn) 485 { type *t; 486 487 //printf("type_allocn(ty = x%x, tn = %p)\n", ty, tn); 488 assert(tn); 489 type_debug(tn); 490 t = type_alloc(ty); 491 t.Tnext = tn; 492 tn.Tcount++; 493 //printf("\tt = %p\n", t); 494 return t; 495 } 496 497 /****************************** 498 * Allocate a TYmemptr type. 499 */ 500 501 version (SCPP_HTOD) 502 { 503 type *type_allocmemptr(Classsym *stag,type *tn) 504 { type *t; 505 506 symbol_debug(stag); 507 assert(stag.Sclass == SCstruct || tybasic(stag.Stype.Tty) == TYident); 508 t = type_allocn(TYmemptr,tn); 509 t.Ttag = stag; 510 //printf("type_allocmemptr() = %p\n", t); 511 //type_print(t); 512 return t; 513 } 514 } 515 516 /******************************** 517 * Allocate a pointer type. 518 * Returns: 519 * Tcount already incremented 520 */ 521 522 type *type_pointer(type *tnext) 523 { 524 type *t = type_allocn(TYnptr, tnext); 525 t.Tcount++; 526 return t; 527 } 528 529 /******************************** 530 * Allocate a dynamic array type. 531 * Returns: 532 * Tcount already incremented 533 */ 534 535 type *type_dyn_array(type *tnext) 536 { 537 type *t = type_allocn(TYdarray, tnext); 538 t.Tcount++; 539 return t; 540 } 541 542 /******************************** 543 * Allocate a static array type. 544 * Returns: 545 * Tcount already incremented 546 */ 547 548 extern (C) type *type_static_array(targ_size_t dim, type *tnext) 549 { 550 type *t = type_allocn(TYarray, tnext); 551 t.Tdim = dim; 552 t.Tcount++; 553 return t; 554 } 555 556 /******************************** 557 * Allocate an associative array type, 558 * which are key=value pairs 559 * Returns: 560 * Tcount already incremented 561 */ 562 563 type *type_assoc_array(type *tkey, type *tvalue) 564 { 565 type *t = type_allocn(TYaarray, tvalue); 566 t.Tkey = tkey; 567 tkey.Tcount++; 568 t.Tcount++; 569 return t; 570 } 571 572 /******************************** 573 * Allocate a delegate type. 574 * Returns: 575 * Tcount already incremented 576 */ 577 578 type *type_delegate(type *tnext) 579 { 580 type *t = type_allocn(TYdelegate, tnext); 581 t.Tcount++; 582 return t; 583 } 584 585 /*********************************** 586 * Allocation a function type. 587 * Params: 588 * tyf = function type 589 * ptypes = types of the function parameters 590 * variadic = if ... function 591 * tret = return type 592 * Returns: 593 * Tcount already incremented 594 */ 595 extern (C) 596 type *type_function(tym_t tyf, type*[] ptypes, bool variadic, type *tret) 597 { 598 param_t *paramtypes = null; 599 foreach (p; ptypes) 600 { 601 param_append_type(¶mtypes, p); 602 } 603 type *t = type_allocn(tyf, tret); 604 t.Tflags |= TFprototype; 605 if (!variadic) 606 t.Tflags |= TFfixed; 607 t.Tparamtypes = paramtypes; 608 t.Tcount++; 609 return t; 610 } 611 612 /*************************************** 613 * Create an enum type. 614 * Input: 615 * name name of enum 616 * tbase "base" type of enum 617 * Returns: 618 * Tcount already incremented 619 */ 620 type *type_enum(const(char)* name, type *tbase) 621 { 622 Symbol *s = symbol_calloc(name); 623 s.Sclass = SCenum; 624 s.Senum = cast(enum_t *) MEM_PH_CALLOC(enum_t.sizeof); 625 s.Senum.SEflags |= SENforward; // forward reference 626 627 type *t = type_allocn(TYenum, tbase); 628 t.Ttag = cast(Classsym *)s; // enum tag name 629 t.Tcount++; 630 s.Stype = t; 631 t.Tcount++; 632 return t; 633 } 634 635 /************************************** 636 * Create a struct/union/class type. 637 * Params: 638 * name = name of struct (this function makes its own copy of the string) 639 * is0size = if struct has no fields (even if Sstructsize is 1) 640 * Returns: 641 * Tcount already incremented 642 */ 643 type *type_struct_class(const(char)* name, uint alignsize, uint structsize, 644 type *arg1type, type *arg2type, bool isUnion, bool isClass, bool isPOD, bool is0size) 645 { 646 Symbol *s = symbol_calloc(name); 647 s.Sclass = SCstruct; 648 s.Sstruct = struct_calloc(); 649 s.Sstruct.Salignsize = alignsize; 650 s.Sstruct.Sstructalign = cast(ubyte)alignsize; 651 s.Sstruct.Sstructsize = structsize; 652 s.Sstruct.Sarg1type = arg1type; 653 s.Sstruct.Sarg2type = arg2type; 654 655 if (!isPOD) 656 s.Sstruct.Sflags |= STRnotpod; 657 if (isUnion) 658 s.Sstruct.Sflags |= STRunion; 659 if (isClass) 660 { s.Sstruct.Sflags |= STRclass; 661 assert(!isUnion && isPOD); 662 } 663 if (is0size) 664 s.Sstruct.Sflags |= STR0size; 665 666 type *t = type_alloc(TYstruct); 667 t.Ttag = cast(Classsym *)s; // structure tag name 668 t.Tcount++; 669 s.Stype = t; 670 t.Tcount++; 671 return t; 672 } 673 674 /***************************** 675 * Free up data type. 676 */ 677 678 void type_free(type *t) 679 { type *tn; 680 tym_t ty; 681 682 while (t) 683 { 684 //printf("type_free(%p, Tcount = %d)\n", t, t.Tcount); 685 type_debug(t); 686 assert(cast(int)t.Tcount != -1); 687 if (--t.Tcount) /* if usage count doesn't go to 0 */ 688 break; 689 ty = tybasic(t.Tty); 690 if (tyfunc(ty)) 691 { param_free(&t.Tparamtypes); 692 list_free(&t.Texcspec, cast(list_free_fp)&type_free); 693 goto L1; 694 } 695 version (SCPP_HTOD) 696 { 697 if (ty == TYtemplate) 698 { 699 param_free(&t.Tparamtypes); 700 goto L1; 701 } 702 if (ty == TYident) 703 { 704 MEM_PH_FREE(t.Tident); 705 goto L1; 706 } 707 } 708 if (t.Tflags & TFvla && t.Tel) 709 { 710 el_free(t.Tel); 711 goto L1; 712 } 713 version (SCPP_HTOD) 714 { 715 if (t.Talternate && typtr(ty)) 716 { 717 type_free(t.Talternate); 718 goto L1; 719 } 720 } 721 version (MARS) 722 { 723 if (t.Tkey && typtr(ty)) 724 type_free(t.Tkey); 725 } 726 L1: 727 728 debug 729 { 730 type_num--; 731 //printf("Free'ing type %p ",t); WRTYxx(t.Tty); printf("\n"); 732 t.id = 0; /* no longer a valid type */ 733 } 734 735 tn = t.Tnext; 736 t.Tnext = type_list; 737 type_list = t; /* link into free list */ 738 t = tn; 739 } 740 } 741 742 version (STATS) 743 { 744 /* count number of free types available on type list */ 745 void type_count_free() 746 { 747 type *t; 748 int count; 749 750 for(t=type_list;t;t=t.Tnext) 751 count++; 752 printf("types on free list %d with max of %d\n",count,type_max); 753 } 754 } 755 756 /********************************** 757 * Initialize type package. 758 */ 759 760 private type * type_allocbasic(tym_t ty) 761 { type *t; 762 763 t = type_alloc(ty); 764 t.Tmangle = mTYman_c; 765 t.Tcount = 1; /* so it is not inadvertently free'd */ 766 return t; 767 } 768 769 void type_init() 770 { 771 tstypes[TYbool] = type_allocbasic(TYbool); 772 tstypes[TYwchar_t] = type_allocbasic(TYwchar_t); 773 tstypes[TYdchar] = type_allocbasic(TYdchar); 774 tstypes[TYvoid] = type_allocbasic(TYvoid); 775 tstypes[TYnullptr] = type_allocbasic(TYnullptr); 776 tstypes[TYchar16] = type_allocbasic(TYchar16); 777 tstypes[TYuchar] = type_allocbasic(TYuchar); 778 tstypes[TYschar] = type_allocbasic(TYschar); 779 tstypes[TYchar] = type_allocbasic(TYchar); 780 tstypes[TYshort] = type_allocbasic(TYshort); 781 tstypes[TYushort] = type_allocbasic(TYushort); 782 tstypes[TYint] = type_allocbasic(TYint); 783 tstypes[TYuint] = type_allocbasic(TYuint); 784 tstypes[TYlong] = type_allocbasic(TYlong); 785 tstypes[TYulong] = type_allocbasic(TYulong); 786 tstypes[TYllong] = type_allocbasic(TYllong); 787 tstypes[TYullong] = type_allocbasic(TYullong); 788 tstypes[TYfloat] = type_allocbasic(TYfloat); 789 tstypes[TYdouble] = type_allocbasic(TYdouble); 790 tstypes[TYdouble_alias] = type_allocbasic(TYdouble_alias); 791 tstypes[TYldouble] = type_allocbasic(TYldouble); 792 tstypes[TYifloat] = type_allocbasic(TYifloat); 793 tstypes[TYidouble] = type_allocbasic(TYidouble); 794 tstypes[TYildouble] = type_allocbasic(TYildouble); 795 tstypes[TYcfloat] = type_allocbasic(TYcfloat); 796 tstypes[TYcdouble] = type_allocbasic(TYcdouble); 797 tstypes[TYcldouble] = type_allocbasic(TYcldouble); 798 799 if (I64) 800 { 801 TYptrdiff = TYllong; 802 TYsize = TYullong; 803 tsptrdiff = tstypes[TYllong]; 804 tssize = tstypes[TYullong]; 805 } 806 else 807 { 808 TYptrdiff = TYint; 809 TYsize = TYuint; 810 tsptrdiff = tstypes[TYint]; 811 tssize = tstypes[TYuint]; 812 } 813 814 // Type of trace function 815 tstrace = type_fake(I16 ? TYffunc : TYnfunc); 816 tstrace.Tmangle = mTYman_c; 817 tstrace.Tcount++; 818 819 chartype = (config.flags3 & CFG3ju) ? tstypes[TYuchar] : tstypes[TYchar]; 820 821 // Type of far library function 822 tsclib = type_fake(LARGECODE ? TYfpfunc : TYnpfunc); 823 tsclib.Tmangle = mTYman_c; 824 tsclib.Tcount++; 825 826 tspvoid = type_allocn(pointertype,tstypes[TYvoid]); 827 tspvoid.Tmangle = mTYman_c; 828 tspvoid.Tcount++; 829 830 // Type of far library function 831 tsjlib = type_fake(TYjfunc); 832 tsjlib.Tmangle = mTYman_c; 833 tsjlib.Tcount++; 834 835 tsdlib = tsjlib; 836 837 version (SCPP_HTOD) 838 { 839 tspcvoid = type_alloc(mTYconst | TYvoid); 840 tspcvoid = newpointer(tspcvoid); 841 tspcvoid.Tmangle = mTYman_c; 842 tspcvoid.Tcount++; 843 } 844 845 // Type of logical expression 846 tslogical = (config.flags4 & CFG4bool) ? tstypes[TYbool] : tstypes[TYint]; 847 848 for (int i = 0; i < TYMAX; i++) 849 { 850 if (tstypes[i]) 851 { tsptr2types[i] = type_allocn(pointertype,tstypes[i]); 852 tsptr2types[i].Tcount++; 853 } 854 } 855 } 856 857 /********************************** 858 * Free type_list. 859 */ 860 861 void type_term() 862 { 863 static if (TERMCODE) 864 { 865 type *tn; 866 param_t *pn; 867 int i; 868 869 for (i = 0; i < tstypes.length; i++) 870 { type *t = tsptr2types[i]; 871 872 if (t) 873 { assert(!(t.Tty & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 874 assert(!(t.Tflags)); 875 assert(!(t.Tmangle)); 876 type_free(t); 877 } 878 type_free(tstypes[i]); 879 } 880 881 type_free(tsclib); 882 type_free(tspvoid); 883 type_free(tspcvoid); 884 type_free(tsjlib); 885 type_free(tstrace); 886 887 while (type_list) 888 { tn = type_list.Tnext; 889 mem_ffree(type_list); 890 type_list = tn; 891 } 892 893 while (param_list) 894 { pn = param_list.Pnext; 895 mem_ffree(param_list); 896 param_list = pn; 897 } 898 899 debug 900 { 901 printf("Max # of types = %d\n",type_max); 902 if (type_num != 0) 903 printf("type_num = %d\n",type_num); 904 /* assert(type_num == 0);*/ 905 } 906 907 } 908 } 909 910 /******************************* 911 * Type type information. 912 */ 913 914 /************************** 915 * Make copy of a type. 916 */ 917 918 type *type_copy(type *t) 919 { type *tn; 920 param_t *p; 921 922 type_debug(t); 923 version (SCPP_HTOD) 924 { 925 if (tybasic(t.Tty) == TYtemplate) 926 { 927 tn = type_alloc_template((cast(typetemp_t *)t).Tsym); 928 } 929 else 930 tn = type_alloc(t.Tty); 931 } 932 else 933 tn = type_alloc(t.Tty); 934 935 *tn = *t; 936 switch (tybasic(tn.Tty)) 937 { 938 version (SCPP_HTOD) 939 { 940 case TYtemplate: 941 (cast(typetemp_t *)tn).Tsym = (cast(typetemp_t *)t).Tsym; 942 goto L1; 943 944 case TYident: 945 tn.Tident = cast(char *)MEM_PH_STRDUP(t.Tident); 946 break; 947 } 948 949 case TYarray: 950 if (tn.Tflags & TFvla) 951 tn.Tel = el_copytree(tn.Tel); 952 break; 953 954 default: 955 if (tyfunc(tn.Tty)) 956 { 957 L1: 958 tn.Tparamtypes = null; 959 for (p = t.Tparamtypes; p; p = p.Pnext) 960 { param_t *pn; 961 962 pn = param_append_type(&tn.Tparamtypes,p.Ptype); 963 if (p.Pident) 964 { 965 pn.Pident = cast(char *)MEM_PH_STRDUP(p.Pident); 966 } 967 assert(!p.Pelem); 968 } 969 } 970 else 971 { 972 version (SCPP_HTOD) 973 { 974 if (tn.Talternate && typtr(tn.Tty)) 975 tn.Talternate.Tcount++; 976 } 977 version (MARS) 978 { 979 if (tn.Tkey && typtr(tn.Tty)) 980 tn.Tkey.Tcount++; 981 } 982 } 983 break; 984 } 985 if (tn.Tnext) 986 { type_debug(tn.Tnext); 987 tn.Tnext.Tcount++; 988 } 989 tn.Tcount = 0; 990 return tn; 991 } 992 993 /************************************ 994 */ 995 996 version (SCPP_HTOD) 997 { 998 999 elem *type_vla_fix(type **pt) 1000 { 1001 type *t; 1002 elem *e = null; 1003 1004 for (t = *pt; t; t = t.Tnext) 1005 { 1006 type_debug(t); 1007 if (tybasic(t.Tty) == TYarray && t.Tflags & TFvla && t.Tel) 1008 { Symbol *s; 1009 elem *ec; 1010 1011 s = symbol_genauto(tstypes[TYuint]); 1012 ec = el_var(s); 1013 ec = el_bint(OPeq, tstypes[TYuint], ec, t.Tel); 1014 e = el_combine(e, ec); 1015 t.Tel = el_var(s); 1016 } 1017 } 1018 return e; 1019 } 1020 1021 } 1022 1023 /**************************** 1024 * Modify the tym_t field of a type. 1025 */ 1026 1027 type *type_setty(type **pt,uint newty) 1028 { type *t; 1029 1030 t = *pt; 1031 type_debug(t); 1032 if (cast(tym_t)newty != t.Tty) 1033 { if (t.Tcount > 1) /* if other people pointing at t */ 1034 { type *tn; 1035 1036 tn = type_copy(t); 1037 tn.Tcount++; 1038 type_free(t); 1039 t = tn; 1040 *pt = t; 1041 } 1042 t.Tty = newty; 1043 } 1044 return t; 1045 } 1046 1047 /****************************** 1048 * Set type field of some object to t. 1049 */ 1050 1051 type *type_settype(type **pt, type *t) 1052 { 1053 if (t) 1054 { type_debug(t); 1055 t.Tcount++; 1056 } 1057 type_free(*pt); 1058 return *pt = t; 1059 } 1060 1061 /**************************** 1062 * Modify the Tmangle field of a type. 1063 */ 1064 1065 type *type_setmangle(type **pt,mangle_t mangle) 1066 { type *t; 1067 1068 t = *pt; 1069 type_debug(t); 1070 if (mangle != type_mangle(t)) 1071 { 1072 if (t.Tcount > 1) // if other people pointing at t 1073 { type *tn; 1074 1075 tn = type_copy(t); 1076 tn.Tcount++; 1077 type_free(t); 1078 t = tn; 1079 *pt = t; 1080 } 1081 t.Tmangle = mangle; 1082 } 1083 return t; 1084 } 1085 1086 /****************************** 1087 * Set/clear const and volatile bits in *pt according to the settings 1088 * in cv. 1089 */ 1090 1091 type *type_setcv(type **pt,tym_t cv) 1092 { uint ty; 1093 1094 type_debug(*pt); 1095 ty = (*pt).Tty & ~(mTYconst | mTYvolatile | mTYimmutable | mTYshared); 1096 return type_setty(pt,ty | (cv & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 1097 } 1098 1099 /***************************** 1100 * Set dimension of array. 1101 */ 1102 1103 type *type_setdim(type **pt,targ_size_t dim) 1104 { type *t = *pt; 1105 1106 type_debug(t); 1107 if (t.Tcount > 1) /* if other people pointing at t */ 1108 { type *tn; 1109 1110 tn = type_copy(t); 1111 tn.Tcount++; 1112 type_free(t); 1113 t = tn; 1114 } 1115 t.Tflags &= ~TFsizeunknown; /* we have determined its size */ 1116 t.Tdim = dim; /* index of array */ 1117 return *pt = t; 1118 } 1119 1120 1121 /***************************** 1122 * Create a 'dependent' version of type t. 1123 */ 1124 1125 type *type_setdependent(type *t) 1126 { 1127 type_debug(t); 1128 if (t.Tcount > 0 && /* if other people pointing at t */ 1129 !(t.Tflags & TFdependent)) 1130 { 1131 t = type_copy(t); 1132 } 1133 t.Tflags |= TFdependent; 1134 return t; 1135 } 1136 1137 /************************************ 1138 * Determine if type t is a dependent type. 1139 */ 1140 1141 int type_isdependent(type *t) 1142 { 1143 Symbol *stempl; 1144 type *tstart; 1145 1146 //printf("type_isdependent(%p)\n", t); 1147 //type_print(t); 1148 for (tstart = t; t; t = t.Tnext) 1149 { 1150 type_debug(t); 1151 if (t.Tflags & TFdependent) 1152 goto Lisdependent; 1153 if (tyfunc(t.Tty) 1154 || tybasic(t.Tty) == TYtemplate 1155 ) 1156 { 1157 for (param_t *p = t.Tparamtypes; p; p = p.Pnext) 1158 { 1159 if (p.Ptype && type_isdependent(p.Ptype)) 1160 goto Lisdependent; 1161 if (p.Pelem && el_isdependent(p.Pelem)) 1162 goto Lisdependent; 1163 } 1164 } 1165 else if (type_struct(t) && 1166 (stempl = t.Ttag.Sstruct.Stempsym) != null) 1167 { 1168 for (param_t *p = t.Ttag.Sstruct.Sarglist; p; p = p.Pnext) 1169 { 1170 if (p.Ptype && type_isdependent(p.Ptype)) 1171 goto Lisdependent; 1172 if (p.Pelem && el_isdependent(p.Pelem)) 1173 goto Lisdependent; 1174 } 1175 } 1176 } 1177 //printf("\tis not dependent\n"); 1178 return 0; 1179 1180 Lisdependent: 1181 //printf("\tis dependent\n"); 1182 // Dependence on a dependent type makes this type dependent as well 1183 tstart.Tflags |= TFdependent; 1184 return 1; 1185 } 1186 1187 1188 /******************************* 1189 * Recursively check if type u is embedded in type t. 1190 * Returns: 1191 * != 0 if embedded 1192 */ 1193 1194 int type_embed(type *t,type *u) 1195 { param_t *p; 1196 1197 for (; t; t = t.Tnext) 1198 { 1199 type_debug(t); 1200 if (t == u) 1201 return 1; 1202 if (tyfunc(t.Tty)) 1203 { 1204 for (p = t.Tparamtypes; p; p = p.Pnext) 1205 if (type_embed(p.Ptype,u)) 1206 return 1; 1207 } 1208 } 1209 return 0; 1210 } 1211 1212 1213 /*********************************** 1214 * Determine if type is a VLA. 1215 */ 1216 1217 int type_isvla(type *t) 1218 { 1219 while (t) 1220 { 1221 if (tybasic(t.Tty) != TYarray) 1222 break; 1223 if (t.Tflags & TFvla) 1224 return 1; 1225 t = t.Tnext; 1226 } 1227 return 0; 1228 } 1229 1230 1231 /********************************** 1232 * Pretty-print a type. 1233 */ 1234 1235 void type_print(const type *t) 1236 { 1237 type_debug(t); 1238 printf("Tty="); WRTYxx(t.Tty); 1239 printf(" Tmangle=%d",t.Tmangle); 1240 printf(" Tflags=x%x",t.Tflags); 1241 printf(" Tcount=%d",t.Tcount); 1242 if (!(t.Tflags & TFsizeunknown) && 1243 tybasic(t.Tty) != TYvoid && 1244 tybasic(t.Tty) != TYident && 1245 tybasic(t.Tty) != TYtemplate && 1246 tybasic(t.Tty) != TYmfunc && 1247 tybasic(t.Tty) != TYarray) 1248 printf(" Tsize=%lld", cast(long)type_size(t)); 1249 printf(" Tnext=%p",t.Tnext); 1250 switch (tybasic(t.Tty)) 1251 { case TYstruct: 1252 case TYmemptr: 1253 printf(" Ttag=%p,'%s'",t.Ttag,t.Ttag.Sident.ptr); 1254 //printf(" Sfldlst=%p",t.Ttag.Sstruct.Sfldlst); 1255 break; 1256 1257 case TYarray: 1258 printf(" Tdim=%lld", cast(long)t.Tdim); 1259 break; 1260 1261 case TYident: 1262 printf(" Tident='%s'",t.Tident); 1263 break; 1264 case TYtemplate: 1265 printf(" Tsym='%s'",(cast(typetemp_t *)t).Tsym.Sident.ptr); 1266 { 1267 int i; 1268 1269 i = 1; 1270 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext) 1271 { printf("\nTP%d (%p): ",i++,p); 1272 fflush(stdout); 1273 1274 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext); 1275 param_debug(p); 1276 if (p.Pident) 1277 printf("'%s' ", p.Pident); 1278 if (p.Ptype) 1279 type_print(p.Ptype); 1280 if (p.Pelem) 1281 elem_print(p.Pelem); 1282 } 1283 } 1284 break; 1285 1286 default: 1287 if (tyfunc(t.Tty)) 1288 { 1289 int i; 1290 1291 i = 1; 1292 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext) 1293 { printf("\nP%d (%p): ",i++,p); 1294 fflush(stdout); 1295 1296 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext); 1297 param_debug(p); 1298 if (p.Pident) 1299 printf("'%s' ", p.Pident); 1300 type_print(p.Ptype); 1301 } 1302 } 1303 break; 1304 } 1305 printf("\n"); 1306 if (t.Tnext) type_print(t.Tnext); 1307 } 1308 1309 /******************************* 1310 * Pretty-print a param_t 1311 */ 1312 1313 void param_t_print(const param_t* p) 1314 { 1315 printf("Pident=%p,Ptype=%p,Pelem=%p,Psym=%p,Pnext=%p\n",p.Pident,p.Ptype,p.Pelem,p.Psym,p.Pnext); 1316 if (p.Pident) 1317 printf("\tPident = '%s'\n", p.Pident); 1318 if (p.Ptype) 1319 { printf("\tPtype =\n"); 1320 type_print(p.Ptype); 1321 } 1322 if (p.Pelem) 1323 { printf("\tPelem =\n"); 1324 elem_print(p.Pelem); 1325 } 1326 if (p.Pdeftype) 1327 { printf("\tPdeftype =\n"); 1328 type_print(p.Pdeftype); 1329 } 1330 if (p.Psym) 1331 { printf("\tPsym = '%s'\n", p.Psym.Sident.ptr); 1332 } 1333 if (p.Pptpl) 1334 { printf("\tPptpl = %p\n", p.Pptpl); 1335 } 1336 } 1337 1338 void param_t_print_list(param_t* p) 1339 { 1340 for (; p; p = p.Pnext) 1341 p.print(); 1342 } 1343 1344 1345 /********************************** 1346 * Hydrate a type. 1347 */ 1348 1349 version (SCPP_HTOD) 1350 { 1351 1352 static if (HYDRATE) 1353 { 1354 void type_hydrate(type **pt) 1355 { 1356 type *t; 1357 1358 assert(pt); 1359 while (isdehydrated(*pt)) 1360 { 1361 t = cast(type *) ph_hydrate(cast(void**)pt); 1362 type_debug(t); 1363 switch (tybasic(t.Tty)) 1364 { 1365 case TYstruct: 1366 case TYenum: 1367 case TYmemptr: 1368 case TYvtshape: 1369 // Cannot assume symbol is hydrated, because entire HX file 1370 // may not have been hydrated. 1371 Classsym_hydrate(&t.Ttag); 1372 symbol_debug(t.Ttag); 1373 break; 1374 case TYident: 1375 ph_hydrate(cast(void**)&t.Tident); 1376 break; 1377 case TYtemplate: 1378 symbol_hydrate(&(cast(typetemp_t *)t).Tsym); 1379 param_hydrate(&t.Tparamtypes); 1380 break; 1381 case TYarray: 1382 if (t.Tflags & TFvla) 1383 el_hydrate(&t.Tel); 1384 break; 1385 default: 1386 if (tyfunc(t.Tty)) 1387 { param_hydrate(&t.Tparamtypes); 1388 list_hydrate(&t.Texcspec, cast(list_free_fp)&type_hydrate); 1389 } 1390 else if (t.Talternate && typtr(t.Tty)) 1391 type_hydrate(&t.Talternate); 1392 else if (t.Tkey && typtr(t.Tty)) 1393 type_hydrate(&t.Tkey); 1394 break; 1395 } 1396 pt = &t.Tnext; 1397 } 1398 } 1399 } 1400 1401 /********************************** 1402 * Dehydrate a type. 1403 */ 1404 1405 static if (DEHYDRATE) 1406 { 1407 void type_dehydrate(type **pt) 1408 { 1409 type *t; 1410 1411 while ((t = *pt) != null && !isdehydrated(t)) 1412 { 1413 ph_dehydrate(pt); 1414 version (DEBUG_XSYMGEN) 1415 { 1416 /* don't dehydrate types in HEAD when creating XSYM */ 1417 if (xsym_gen && (t.Tflags & TFhydrated)) 1418 return; 1419 } 1420 type_debug(t); 1421 switch (tybasic(t.Tty)) 1422 { 1423 case TYstruct: 1424 case TYenum: 1425 case TYmemptr: 1426 case TYvtshape: 1427 Classsym_dehydrate(&t.Ttag); 1428 break; 1429 case TYident: 1430 ph_dehydrate(&t.Tident); 1431 break; 1432 case TYtemplate: 1433 symbol_dehydrate(&(cast(typetemp_t *)t).Tsym); 1434 param_dehydrate(&t.Tparamtypes); 1435 break; 1436 case TYarray: 1437 if (t.Tflags & TFvla) 1438 el_dehydrate(&t.Tel); 1439 break; 1440 default: 1441 if (tyfunc(t.Tty)) 1442 { param_dehydrate(&t.Tparamtypes); 1443 list_dehydrate(&t.Texcspec, cast(list_free_fp)&type_dehydrate); 1444 } 1445 else if (t.Talternate && typtr(t.Tty)) 1446 type_dehydrate(&t.Talternate); 1447 else if (t.Tkey && typtr(t.Tty)) 1448 type_dehydrate(&t.Tkey); 1449 break; 1450 } 1451 pt = &t.Tnext; 1452 } 1453 } 1454 } 1455 1456 } 1457 1458 /**************************** 1459 * Allocate a param_t. 1460 */ 1461 1462 param_t *param_calloc() 1463 { 1464 static param_t pzero; 1465 param_t *p; 1466 1467 if (param_list) 1468 { 1469 p = param_list; 1470 param_list = p.Pnext; 1471 } 1472 else 1473 { 1474 p = cast(param_t *) mem_fmalloc(param_t.sizeof); 1475 } 1476 *p = pzero; 1477 1478 debug p.id = param_t.IDparam; 1479 1480 return p; 1481 } 1482 1483 /*************************** 1484 * Allocate a param_t of type t, and append it to parameter list. 1485 */ 1486 1487 param_t *param_append_type(param_t **pp,type *t) 1488 { param_t *p; 1489 1490 p = param_calloc(); 1491 while (*pp) 1492 { param_debug(*pp); 1493 pp = &((*pp).Pnext); /* find end of list */ 1494 } 1495 *pp = p; /* append p to list */ 1496 type_debug(t); 1497 p.Ptype = t; 1498 t.Tcount++; 1499 return p; 1500 } 1501 1502 /************************ 1503 * Version of param_free() suitable for list_free(). 1504 */ 1505 1506 void param_free_l(param_t *p) 1507 { 1508 param_free(&p); 1509 } 1510 1511 /*********************** 1512 * Free parameter list. 1513 * Output: 1514 * paramlst = null 1515 */ 1516 1517 void param_free(param_t **pparamlst) 1518 { param_t* p,pn; 1519 1520 //debug_assert(PARSER); 1521 for (p = *pparamlst; p; p = pn) 1522 { param_debug(p); 1523 pn = p.Pnext; 1524 type_free(p.Ptype); 1525 mem_free(p.Pident); 1526 el_free(p.Pelem); 1527 type_free(p.Pdeftype); 1528 if (p.Pptpl) 1529 param_free(&p.Pptpl); 1530 1531 debug p.id = 0; 1532 1533 p.Pnext = param_list; 1534 param_list = p; 1535 } 1536 *pparamlst = null; 1537 } 1538 1539 /*********************************** 1540 * Compute number of parameters 1541 */ 1542 1543 uint param_t_length(param_t* p) 1544 { 1545 uint nparams = 0; 1546 1547 for (; p; p = p.Pnext) 1548 nparams++; 1549 return nparams; 1550 } 1551 1552 /************************************* 1553 * Create template-argument-list blank from 1554 * template-parameter-list 1555 * Input: 1556 * ptali initial template-argument-list 1557 */ 1558 1559 param_t *param_t_createTal(param_t* p, param_t *ptali) 1560 { 1561 version (SCPP_HTOD) 1562 { 1563 param_t *ptalistart = ptali; 1564 param_t *pstart = p; 1565 } 1566 param_t *ptal = null; 1567 param_t **pp = &ptal; 1568 1569 for (; p; p = p.Pnext) 1570 { 1571 *pp = param_calloc(); 1572 if (p.Pident) 1573 { 1574 // Should find a way to just point rather than dup 1575 (*pp).Pident = cast(char *)MEM_PH_STRDUP(p.Pident); 1576 } 1577 if (ptali) 1578 { 1579 if (ptali.Ptype) 1580 { (*pp).Ptype = ptali.Ptype; 1581 (*pp).Ptype.Tcount++; 1582 } 1583 if (ptali.Pelem) 1584 { 1585 elem *e = el_copytree(ptali.Pelem); 1586 version (SCPP_HTOD) 1587 { 1588 if (p.Ptype) 1589 { type *t = p.Ptype; 1590 t = template_tyident(t, ptalistart, pstart, 1); 1591 e = poptelem3(typechk(e, t)); 1592 type_free(t); 1593 } 1594 } 1595 (*pp).Pelem = e; 1596 } 1597 (*pp).Psym = ptali.Psym; 1598 (*pp).Pflags = ptali.Pflags; 1599 assert(!ptali.Pptpl); 1600 ptali = ptali.Pnext; 1601 } 1602 pp = &(*pp).Pnext; 1603 } 1604 return ptal; 1605 } 1606 1607 /********************************** 1608 * Look for Pident matching id 1609 */ 1610 1611 param_t *param_t_search(param_t* p, char *id) 1612 { 1613 for (; p; p = p.Pnext) 1614 { 1615 if (p.Pident && strcmp(p.Pident, id) == 0) 1616 break; 1617 } 1618 return p; 1619 } 1620 1621 /********************************** 1622 * Look for Pident matching id 1623 */ 1624 1625 int param_t_searchn(param_t* p, char *id) 1626 { 1627 int n = 0; 1628 1629 for (; p; p = p.Pnext) 1630 { 1631 if (p.Pident && strcmp(p.Pident, id) == 0) 1632 return n; 1633 n++; 1634 } 1635 return -1; 1636 } 1637 1638 /************************************* 1639 * Search for member, create symbol as needed. 1640 * Used for symbol tables for VLA's such as: 1641 * void func(int n, int a[n]); 1642 */ 1643 1644 Symbol *param_search(const(char)* name, param_t **pp) 1645 { Symbol *s = null; 1646 param_t *p; 1647 1648 p = (*pp).search(cast(char *)name); 1649 if (p) 1650 { 1651 s = p.Psym; 1652 if (!s) 1653 { 1654 s = symbol_calloc(p.Pident); 1655 s.Sclass = SCparameter; 1656 s.Stype = p.Ptype; 1657 s.Stype.Tcount++; 1658 p.Psym = s; 1659 } 1660 } 1661 return s; 1662 } 1663 1664 /********************************** 1665 * Hydrate/dehydrate a type. 1666 */ 1667 1668 version (SCPP_HTOD) 1669 { 1670 static if (HYDRATE) 1671 { 1672 void param_hydrate(param_t **pp) 1673 { 1674 param_t *p; 1675 1676 assert(pp); 1677 if (isdehydrated(*pp)) 1678 { while (*pp) 1679 { assert(isdehydrated(*pp)); 1680 p = cast(param_t *) ph_hydrate(cast(void**)pp); 1681 param_debug(p); 1682 1683 type_hydrate(&p.Ptype); 1684 if (p.Ptype) 1685 type_debug(p.Ptype); 1686 ph_hydrate(cast(void**)&p.Pident); 1687 if (CPP) 1688 { 1689 el_hydrate(&p.Pelem); 1690 if (p.Pelem) 1691 elem_debug(p.Pelem); 1692 type_hydrate(&p.Pdeftype); 1693 if (p.Pptpl) 1694 param_hydrate(&p.Pptpl); 1695 if (p.Psym) 1696 symbol_hydrate(&p.Psym); 1697 if (p.PelemToken) 1698 token_hydrate(&p.PelemToken); 1699 } 1700 1701 pp = &p.Pnext; 1702 } 1703 } 1704 } 1705 } 1706 1707 static if (DEHYDRATE) 1708 { 1709 void param_dehydrate(param_t **pp) 1710 { 1711 param_t *p; 1712 1713 assert(pp); 1714 while ((p = *pp) != null && !isdehydrated(p)) 1715 { param_debug(p); 1716 1717 ph_dehydrate(pp); 1718 if (p.Ptype && !isdehydrated(p.Ptype)) 1719 type_debug(p.Ptype); 1720 type_dehydrate(&p.Ptype); 1721 ph_dehydrate(&p.Pident); 1722 if (CPP) 1723 { 1724 el_dehydrate(&p.Pelem); 1725 type_dehydrate(&p.Pdeftype); 1726 if (p.Pptpl) 1727 param_dehydrate(&p.Pptpl); 1728 if (p.Psym) 1729 symbol_dehydrate(&p.Psym); 1730 if (p.PelemToken) 1731 token_dehydrate(&p.PelemToken); 1732 } 1733 pp = &p.Pnext; 1734 } 1735 } 1736 } 1737 } 1738 1739 version (MARS) 1740 { 1741 1742 int typematch(type *t1, type *t2, int relax); 1743 1744 // Return TRUE if type lists match. 1745 private int paramlstmatch(param_t *p1,param_t *p2) 1746 { 1747 return p1 == p2 || 1748 p1 && p2 && typematch(p1.Ptype,p2.Ptype,0) && 1749 paramlstmatch(p1.Pnext,p2.Pnext) 1750 ; 1751 } 1752 1753 /************************************************* 1754 * A cheap version of exp2.typematch() and exp2.paramlstmatch(), 1755 * so that we can get cpp_mangle() to work for MARS. 1756 * It's less complex because it doesn't do templates and 1757 * can rely on strict typechecking. 1758 * Returns: 1759 * !=0 if types match. 1760 */ 1761 1762 int typematch(type *t1,type *t2,int relax) 1763 { tym_t t1ty, t2ty; 1764 tym_t tym; 1765 1766 tym = ~(mTYimport | mTYnaked); 1767 1768 return t1 == t2 || 1769 t1 && t2 && 1770 1771 ( 1772 /* ignore name mangling */ 1773 (t1ty = (t1.Tty & tym)) == (t2ty = (t2.Tty & tym)) 1774 ) 1775 && 1776 1777 (tybasic(t1ty) != TYarray || t1.Tdim == t2.Tdim || 1778 t1.Tflags & TFsizeunknown || t2.Tflags & TFsizeunknown) 1779 && 1780 1781 (tybasic(t1ty) != TYstruct 1782 && tybasic(t1ty) != TYenum 1783 && tybasic(t1ty) != TYmemptr 1784 || t1.Ttag == t2.Ttag) 1785 && 1786 1787 typematch(t1.Tnext,t2.Tnext, 0) 1788 && 1789 1790 (!tyfunc(t1ty) || 1791 ((t1.Tflags & TFfixed) == (t2.Tflags & TFfixed) && 1792 paramlstmatch(t1.Tparamtypes,t2.Tparamtypes) )) 1793 ; 1794 } 1795 1796 } 1797 1798 }