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