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-2021 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 399 assert(tybasic(ty) != TYtemplate); 400 if (type_list) 401 { t = type_list; 402 type_list = t.Tnext; 403 } 404 else 405 t = cast(type *) mem_fmalloc(type.sizeof); 406 *t = type(); 407 t.Tty = ty; 408 version (SRCPOS_4TYPES) 409 { 410 if (PARSER && config.fulltypes) 411 t.Tsrcpos = getlinnum(); 412 } 413 debug 414 { 415 t.id = type.IDtype; 416 type_num++; 417 if (type_num > type_max) 418 type_max = type_num; 419 } 420 //printf("type_alloc() = %p ",t); WRTYxx(t.Tty); printf("\n"); 421 //if (t == (type*)0xB6B744) *(char*)0=0; 422 return t; 423 } 424 425 /************************************* 426 * Allocate a TYtemplate. 427 */ 428 429 version (SCPP_HTOD) 430 { 431 type *type_alloc_template(Symbol *s) 432 { type *t; 433 434 t = cast(type *) mem_fmalloc(typetemp_t.sizeof); 435 memset(t, 0, typetemp_t.sizeof); 436 t.Tty = TYtemplate; 437 if (s.Stemplate.TMprimary) 438 s = s.Stemplate.TMprimary; 439 (cast(typetemp_t *)t).Tsym = s; 440 version (SRCPOS_4TYPES) 441 { 442 if (PARSER && config.fulltypes) 443 t.Tsrcpos = getlinnum(); 444 } 445 debug 446 { 447 t.id = type.IDtype; 448 type_num++; 449 if (type_num > type_max) 450 type_max = type_num; 451 //printf("Alloc'ing template type %p ",t); WRTYxx(t.Tty); printf("\n"); 452 } 453 return t; 454 } 455 } 456 457 /***************************** 458 * Fake a type & initialize it. 459 * Input: 460 * ty = TYxxxx 461 * Returns: 462 * pointer to newly created type. 463 */ 464 465 type *type_fake(tym_t ty) 466 { type *t; 467 468 version (MARS) 469 assert(ty != TYstruct); 470 471 t = type_alloc(ty); 472 if (typtr(ty) || tyfunc(ty)) 473 { t.Tnext = type_alloc(TYvoid); /* fake with pointer to void */ 474 t.Tnext.Tcount = 1; 475 } 476 return t; 477 } 478 479 /***************************** 480 * Allocate a type of ty with a Tnext of tn. 481 */ 482 483 type *type_allocn(tym_t ty,type *tn) 484 { type *t; 485 486 //printf("type_allocn(ty = x%x, tn = %p)\n", ty, tn); 487 assert(tn); 488 type_debug(tn); 489 t = type_alloc(ty); 490 t.Tnext = tn; 491 tn.Tcount++; 492 //printf("\tt = %p\n", t); 493 return t; 494 } 495 496 /****************************** 497 * Allocate a TYmemptr type. 498 */ 499 500 version (SCPP_HTOD) 501 { 502 type *type_allocmemptr(Classsym *stag,type *tn) 503 { type *t; 504 505 symbol_debug(stag); 506 assert(stag.Sclass == SCstruct || tybasic(stag.Stype.Tty) == TYident); 507 t = type_allocn(TYmemptr,tn); 508 t.Ttag = stag; 509 //printf("type_allocmemptr() = %p\n", t); 510 //type_print(t); 511 return t; 512 } 513 } 514 515 /******************************** 516 * Allocate a pointer type. 517 * Returns: 518 * Tcount already incremented 519 */ 520 521 type *type_pointer(type *tnext) 522 { 523 type *t = type_allocn(TYnptr, tnext); 524 t.Tcount++; 525 return t; 526 } 527 528 /******************************** 529 * Allocate a dynamic array type. 530 * Returns: 531 * Tcount already incremented 532 */ 533 534 type *type_dyn_array(type *tnext) 535 { 536 type *t = type_allocn(TYdarray, tnext); 537 t.Tcount++; 538 return t; 539 } 540 541 /******************************** 542 * Allocate a static array type. 543 * Returns: 544 * Tcount already incremented 545 */ 546 547 extern (C) type *type_static_array(targ_size_t dim, type *tnext) 548 { 549 type *t = type_allocn(TYarray, tnext); 550 t.Tdim = dim; 551 t.Tcount++; 552 return t; 553 } 554 555 /******************************** 556 * Allocate an associative array type, 557 * which are key=value pairs 558 * Returns: 559 * Tcount already incremented 560 */ 561 562 type *type_assoc_array(type *tkey, type *tvalue) 563 { 564 type *t = type_allocn(TYaarray, tvalue); 565 t.Tkey = tkey; 566 tkey.Tcount++; 567 t.Tcount++; 568 return t; 569 } 570 571 /******************************** 572 * Allocate a delegate type. 573 * Returns: 574 * Tcount already incremented 575 */ 576 577 type *type_delegate(type *tnext) 578 { 579 type *t = type_allocn(TYdelegate, tnext); 580 t.Tcount++; 581 return t; 582 } 583 584 /*********************************** 585 * Allocation a function type. 586 * Params: 587 * tyf = function type 588 * ptypes = types of the function parameters 589 * variadic = if ... function 590 * tret = return type 591 * Returns: 592 * Tcount already incremented 593 */ 594 extern (C) 595 type *type_function(tym_t tyf, type*[] ptypes, bool variadic, type *tret) 596 { 597 param_t *paramtypes = null; 598 foreach (p; ptypes) 599 { 600 param_append_type(¶mtypes, p); 601 } 602 type *t = type_allocn(tyf, tret); 603 t.Tflags |= TFprototype; 604 if (!variadic) 605 t.Tflags |= TFfixed; 606 t.Tparamtypes = paramtypes; 607 t.Tcount++; 608 return t; 609 } 610 611 /*************************************** 612 * Create an enum type. 613 * Input: 614 * name name of enum 615 * tbase "base" type of enum 616 * Returns: 617 * Tcount already incremented 618 */ 619 type *type_enum(const(char)* name, type *tbase) 620 { 621 Symbol *s = symbol_calloc(name); 622 s.Sclass = SCenum; 623 s.Senum = cast(enum_t *) MEM_PH_CALLOC(enum_t.sizeof); 624 s.Senum.SEflags |= SENforward; // forward reference 625 626 type *t = type_allocn(TYenum, tbase); 627 t.Ttag = cast(Classsym *)s; // enum tag name 628 t.Tcount++; 629 s.Stype = t; 630 t.Tcount++; 631 return t; 632 } 633 634 /************************************** 635 * Create a struct/union/class type. 636 * Params: 637 * name = name of struct (this function makes its own copy of the string) 638 * is0size = if struct has no fields (even if Sstructsize is 1) 639 * Returns: 640 * Tcount already incremented 641 */ 642 type *type_struct_class(const(char)* name, uint alignsize, uint structsize, 643 type *arg1type, type *arg2type, bool isUnion, bool isClass, bool isPOD, bool is0size) 644 { 645 Symbol *s = symbol_calloc(name); 646 s.Sclass = SCstruct; 647 s.Sstruct = struct_calloc(); 648 s.Sstruct.Salignsize = alignsize; 649 s.Sstruct.Sstructalign = cast(ubyte)alignsize; 650 s.Sstruct.Sstructsize = structsize; 651 s.Sstruct.Sarg1type = arg1type; 652 s.Sstruct.Sarg2type = arg2type; 653 654 if (!isPOD) 655 s.Sstruct.Sflags |= STRnotpod; 656 if (isUnion) 657 s.Sstruct.Sflags |= STRunion; 658 if (isClass) 659 { s.Sstruct.Sflags |= STRclass; 660 assert(!isUnion && isPOD); 661 } 662 if (is0size) 663 s.Sstruct.Sflags |= STR0size; 664 665 type *t = type_alloc(TYstruct); 666 t.Ttag = cast(Classsym *)s; // structure tag name 667 t.Tcount++; 668 s.Stype = t; 669 t.Tcount++; 670 return t; 671 } 672 673 /***************************** 674 * Free up data type. 675 */ 676 677 void type_free(type *t) 678 { type *tn; 679 tym_t ty; 680 681 while (t) 682 { 683 //printf("type_free(%p, Tcount = %d)\n", t, t.Tcount); 684 type_debug(t); 685 assert(cast(int)t.Tcount != -1); 686 if (--t.Tcount) /* if usage count doesn't go to 0 */ 687 break; 688 ty = tybasic(t.Tty); 689 if (tyfunc(ty)) 690 { param_free(&t.Tparamtypes); 691 list_free(&t.Texcspec, cast(list_free_fp)&type_free); 692 goto L1; 693 } 694 version (SCPP_HTOD) 695 { 696 if (ty == TYtemplate) 697 { 698 param_free(&t.Tparamtypes); 699 goto L1; 700 } 701 if (ty == TYident) 702 { 703 MEM_PH_FREE(t.Tident); 704 goto L1; 705 } 706 } 707 if (t.Tflags & TFvla && t.Tel) 708 { 709 el_free(t.Tel); 710 goto L1; 711 } 712 version (SCPP_HTOD) 713 { 714 if (t.Talternate && typtr(ty)) 715 { 716 type_free(t.Talternate); 717 goto L1; 718 } 719 } 720 version (MARS) 721 { 722 if (t.Tkey && typtr(ty)) 723 type_free(t.Tkey); 724 } 725 L1: 726 727 debug 728 { 729 type_num--; 730 //printf("Free'ing type %p ",t); WRTYxx(t.Tty); printf("\n"); 731 t.id = 0; /* no longer a valid type */ 732 } 733 734 tn = t.Tnext; 735 t.Tnext = type_list; 736 type_list = t; /* link into free list */ 737 t = tn; 738 } 739 } 740 741 version (STATS) 742 { 743 /* count number of free types available on type list */ 744 void type_count_free() 745 { 746 type *t; 747 int count; 748 749 for(t=type_list;t;t=t.Tnext) 750 count++; 751 printf("types on free list %d with max of %d\n",count,type_max); 752 } 753 } 754 755 /********************************** 756 * Initialize type package. 757 */ 758 759 private type * type_allocbasic(tym_t ty) 760 { type *t; 761 762 t = type_alloc(ty); 763 t.Tmangle = mTYman_c; 764 t.Tcount = 1; /* so it is not inadvertently free'd */ 765 return t; 766 } 767 768 void type_init() 769 { 770 tstypes[TYbool] = type_allocbasic(TYbool); 771 tstypes[TYwchar_t] = type_allocbasic(TYwchar_t); 772 tstypes[TYdchar] = type_allocbasic(TYdchar); 773 tstypes[TYvoid] = type_allocbasic(TYvoid); 774 tstypes[TYnullptr] = type_allocbasic(TYnullptr); 775 tstypes[TYchar16] = type_allocbasic(TYchar16); 776 tstypes[TYuchar] = type_allocbasic(TYuchar); 777 tstypes[TYschar] = type_allocbasic(TYschar); 778 tstypes[TYchar] = type_allocbasic(TYchar); 779 tstypes[TYshort] = type_allocbasic(TYshort); 780 tstypes[TYushort] = type_allocbasic(TYushort); 781 tstypes[TYint] = type_allocbasic(TYint); 782 tstypes[TYuint] = type_allocbasic(TYuint); 783 tstypes[TYlong] = type_allocbasic(TYlong); 784 tstypes[TYulong] = type_allocbasic(TYulong); 785 tstypes[TYllong] = type_allocbasic(TYllong); 786 tstypes[TYullong] = type_allocbasic(TYullong); 787 tstypes[TYfloat] = type_allocbasic(TYfloat); 788 tstypes[TYdouble] = type_allocbasic(TYdouble); 789 tstypes[TYdouble_alias] = type_allocbasic(TYdouble_alias); 790 tstypes[TYldouble] = type_allocbasic(TYldouble); 791 tstypes[TYifloat] = type_allocbasic(TYifloat); 792 tstypes[TYidouble] = type_allocbasic(TYidouble); 793 tstypes[TYildouble] = type_allocbasic(TYildouble); 794 tstypes[TYcfloat] = type_allocbasic(TYcfloat); 795 tstypes[TYcdouble] = type_allocbasic(TYcdouble); 796 tstypes[TYcldouble] = type_allocbasic(TYcldouble); 797 798 if (I64) 799 { 800 TYptrdiff = TYllong; 801 TYsize = TYullong; 802 tsptrdiff = tstypes[TYllong]; 803 tssize = tstypes[TYullong]; 804 } 805 else 806 { 807 TYptrdiff = TYint; 808 TYsize = TYuint; 809 tsptrdiff = tstypes[TYint]; 810 tssize = tstypes[TYuint]; 811 } 812 813 // Type of trace function 814 tstrace = type_fake(I16 ? TYffunc : TYnfunc); 815 tstrace.Tmangle = mTYman_c; 816 tstrace.Tcount++; 817 818 chartype = (config.flags3 & CFG3ju) ? tstypes[TYuchar] : tstypes[TYchar]; 819 820 // Type of far library function 821 tsclib = type_fake(LARGECODE ? TYfpfunc : TYnpfunc); 822 tsclib.Tmangle = mTYman_c; 823 tsclib.Tcount++; 824 825 tspvoid = type_allocn(pointertype,tstypes[TYvoid]); 826 tspvoid.Tmangle = mTYman_c; 827 tspvoid.Tcount++; 828 829 // Type of far library function 830 tsjlib = type_fake(TYjfunc); 831 tsjlib.Tmangle = mTYman_c; 832 tsjlib.Tcount++; 833 834 tsdlib = tsjlib; 835 836 version (SCPP_HTOD) 837 { 838 tspcvoid = type_alloc(mTYconst | TYvoid); 839 tspcvoid = newpointer(tspcvoid); 840 tspcvoid.Tmangle = mTYman_c; 841 tspcvoid.Tcount++; 842 } 843 844 // Type of logical expression 845 tslogical = (config.flags4 & CFG4bool) ? tstypes[TYbool] : tstypes[TYint]; 846 847 for (int i = 0; i < TYMAX; i++) 848 { 849 if (tstypes[i]) 850 { tsptr2types[i] = type_allocn(pointertype,tstypes[i]); 851 tsptr2types[i].Tcount++; 852 } 853 } 854 } 855 856 /********************************** 857 * Free type_list. 858 */ 859 860 void type_term() 861 { 862 static if (TERMCODE) 863 { 864 type *tn; 865 param_t *pn; 866 int i; 867 868 for (i = 0; i < tstypes.length; i++) 869 { type *t = tsptr2types[i]; 870 871 if (t) 872 { assert(!(t.Tty & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 873 assert(!(t.Tflags)); 874 assert(!(t.Tmangle)); 875 type_free(t); 876 } 877 type_free(tstypes[i]); 878 } 879 880 type_free(tsclib); 881 type_free(tspvoid); 882 type_free(tspcvoid); 883 type_free(tsjlib); 884 type_free(tstrace); 885 886 while (type_list) 887 { tn = type_list.Tnext; 888 mem_ffree(type_list); 889 type_list = tn; 890 } 891 892 while (param_list) 893 { pn = param_list.Pnext; 894 mem_ffree(param_list); 895 param_list = pn; 896 } 897 898 debug 899 { 900 printf("Max # of types = %d\n",type_max); 901 if (type_num != 0) 902 printf("type_num = %d\n",type_num); 903 /* assert(type_num == 0);*/ 904 } 905 906 } 907 } 908 909 /******************************* 910 * Type type information. 911 */ 912 913 /************************** 914 * Make copy of a type. 915 */ 916 917 type *type_copy(type *t) 918 { type *tn; 919 param_t *p; 920 921 type_debug(t); 922 version (SCPP_HTOD) 923 { 924 if (tybasic(t.Tty) == TYtemplate) 925 { 926 tn = type_alloc_template((cast(typetemp_t *)t).Tsym); 927 } 928 else 929 tn = type_alloc(t.Tty); 930 } 931 else 932 tn = type_alloc(t.Tty); 933 934 *tn = *t; 935 switch (tybasic(tn.Tty)) 936 { 937 version (SCPP_HTOD) 938 { 939 case TYtemplate: 940 (cast(typetemp_t *)tn).Tsym = (cast(typetemp_t *)t).Tsym; 941 goto L1; 942 943 case TYident: 944 tn.Tident = cast(char *)MEM_PH_STRDUP(t.Tident); 945 break; 946 } 947 948 case TYarray: 949 if (tn.Tflags & TFvla) 950 tn.Tel = el_copytree(tn.Tel); 951 break; 952 953 default: 954 if (tyfunc(tn.Tty)) 955 { 956 L1: 957 tn.Tparamtypes = null; 958 for (p = t.Tparamtypes; p; p = p.Pnext) 959 { param_t *pn; 960 961 pn = param_append_type(&tn.Tparamtypes,p.Ptype); 962 if (p.Pident) 963 { 964 pn.Pident = cast(char *)MEM_PH_STRDUP(p.Pident); 965 } 966 assert(!p.Pelem); 967 } 968 } 969 else 970 { 971 version (SCPP_HTOD) 972 { 973 if (tn.Talternate && typtr(tn.Tty)) 974 tn.Talternate.Tcount++; 975 } 976 version (MARS) 977 { 978 if (tn.Tkey && typtr(tn.Tty)) 979 tn.Tkey.Tcount++; 980 } 981 } 982 break; 983 } 984 if (tn.Tnext) 985 { type_debug(tn.Tnext); 986 tn.Tnext.Tcount++; 987 } 988 tn.Tcount = 0; 989 return tn; 990 } 991 992 /************************************ 993 */ 994 995 version (SCPP_HTOD) 996 { 997 998 elem *type_vla_fix(type **pt) 999 { 1000 type *t; 1001 elem *e = null; 1002 1003 for (t = *pt; t; t = t.Tnext) 1004 { 1005 type_debug(t); 1006 if (tybasic(t.Tty) == TYarray && t.Tflags & TFvla && t.Tel) 1007 { Symbol *s; 1008 elem *ec; 1009 1010 s = symbol_genauto(tstypes[TYuint]); 1011 ec = el_var(s); 1012 ec = el_bint(OPeq, tstypes[TYuint], ec, t.Tel); 1013 e = el_combine(e, ec); 1014 t.Tel = el_var(s); 1015 } 1016 } 1017 return e; 1018 } 1019 1020 } 1021 1022 /**************************** 1023 * Modify the tym_t field of a type. 1024 */ 1025 1026 type *type_setty(type **pt,uint newty) 1027 { type *t; 1028 1029 t = *pt; 1030 type_debug(t); 1031 if (cast(tym_t)newty != t.Tty) 1032 { if (t.Tcount > 1) /* if other people pointing at t */ 1033 { type *tn; 1034 1035 tn = type_copy(t); 1036 tn.Tcount++; 1037 type_free(t); 1038 t = tn; 1039 *pt = t; 1040 } 1041 t.Tty = newty; 1042 } 1043 return t; 1044 } 1045 1046 /****************************** 1047 * Set type field of some object to t. 1048 */ 1049 1050 type *type_settype(type **pt, type *t) 1051 { 1052 if (t) 1053 { type_debug(t); 1054 t.Tcount++; 1055 } 1056 type_free(*pt); 1057 return *pt = t; 1058 } 1059 1060 /**************************** 1061 * Modify the Tmangle field of a type. 1062 */ 1063 1064 type *type_setmangle(type **pt,mangle_t mangle) 1065 { type *t; 1066 1067 t = *pt; 1068 type_debug(t); 1069 if (mangle != type_mangle(t)) 1070 { 1071 if (t.Tcount > 1) // if other people pointing at t 1072 { type *tn; 1073 1074 tn = type_copy(t); 1075 tn.Tcount++; 1076 type_free(t); 1077 t = tn; 1078 *pt = t; 1079 } 1080 t.Tmangle = mangle; 1081 } 1082 return t; 1083 } 1084 1085 /****************************** 1086 * Set/clear const and volatile bits in *pt according to the settings 1087 * in cv. 1088 */ 1089 1090 type *type_setcv(type **pt,tym_t cv) 1091 { uint ty; 1092 1093 type_debug(*pt); 1094 ty = (*pt).Tty & ~(mTYconst | mTYvolatile | mTYimmutable | mTYshared); 1095 return type_setty(pt,ty | (cv & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 1096 } 1097 1098 /***************************** 1099 * Set dimension of array. 1100 */ 1101 1102 type *type_setdim(type **pt,targ_size_t dim) 1103 { type *t = *pt; 1104 1105 type_debug(t); 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 } 1114 t.Tflags &= ~TFsizeunknown; /* we have determined its size */ 1115 t.Tdim = dim; /* index of array */ 1116 return *pt = t; 1117 } 1118 1119 1120 /***************************** 1121 * Create a 'dependent' version of type t. 1122 */ 1123 1124 type *type_setdependent(type *t) 1125 { 1126 type_debug(t); 1127 if (t.Tcount > 0 && /* if other people pointing at t */ 1128 !(t.Tflags & TFdependent)) 1129 { 1130 t = type_copy(t); 1131 } 1132 t.Tflags |= TFdependent; 1133 return t; 1134 } 1135 1136 /************************************ 1137 * Determine if type t is a dependent type. 1138 */ 1139 1140 int type_isdependent(type *t) 1141 { 1142 Symbol *stempl; 1143 type *tstart; 1144 1145 //printf("type_isdependent(%p)\n", t); 1146 //type_print(t); 1147 for (tstart = t; t; t = t.Tnext) 1148 { 1149 type_debug(t); 1150 if (t.Tflags & TFdependent) 1151 goto Lisdependent; 1152 if (tyfunc(t.Tty) 1153 || tybasic(t.Tty) == TYtemplate 1154 ) 1155 { 1156 for (param_t *p = t.Tparamtypes; p; p = p.Pnext) 1157 { 1158 if (p.Ptype && type_isdependent(p.Ptype)) 1159 goto Lisdependent; 1160 if (p.Pelem && el_isdependent(p.Pelem)) 1161 goto Lisdependent; 1162 } 1163 } 1164 else if (type_struct(t) && 1165 (stempl = t.Ttag.Sstruct.Stempsym) != null) 1166 { 1167 for (param_t *p = t.Ttag.Sstruct.Sarglist; p; p = p.Pnext) 1168 { 1169 if (p.Ptype && type_isdependent(p.Ptype)) 1170 goto Lisdependent; 1171 if (p.Pelem && el_isdependent(p.Pelem)) 1172 goto Lisdependent; 1173 } 1174 } 1175 } 1176 //printf("\tis not dependent\n"); 1177 return 0; 1178 1179 Lisdependent: 1180 //printf("\tis dependent\n"); 1181 // Dependence on a dependent type makes this type dependent as well 1182 tstart.Tflags |= TFdependent; 1183 return 1; 1184 } 1185 1186 1187 /******************************* 1188 * Recursively check if type u is embedded in type t. 1189 * Returns: 1190 * != 0 if embedded 1191 */ 1192 1193 int type_embed(type *t,type *u) 1194 { param_t *p; 1195 1196 for (; t; t = t.Tnext) 1197 { 1198 type_debug(t); 1199 if (t == u) 1200 return 1; 1201 if (tyfunc(t.Tty)) 1202 { 1203 for (p = t.Tparamtypes; p; p = p.Pnext) 1204 if (type_embed(p.Ptype,u)) 1205 return 1; 1206 } 1207 } 1208 return 0; 1209 } 1210 1211 1212 /*********************************** 1213 * Determine if type is a VLA. 1214 */ 1215 1216 int type_isvla(type *t) 1217 { 1218 while (t) 1219 { 1220 if (tybasic(t.Tty) != TYarray) 1221 break; 1222 if (t.Tflags & TFvla) 1223 return 1; 1224 t = t.Tnext; 1225 } 1226 return 0; 1227 } 1228 1229 1230 /********************************** 1231 * Pretty-print a type. 1232 */ 1233 1234 void type_print(const type *t) 1235 { 1236 type_debug(t); 1237 printf("Tty="); WRTYxx(t.Tty); 1238 printf(" Tmangle=%d",t.Tmangle); 1239 printf(" Tflags=x%x",t.Tflags); 1240 printf(" Tcount=%d",t.Tcount); 1241 if (!(t.Tflags & TFsizeunknown) && 1242 tybasic(t.Tty) != TYvoid && 1243 tybasic(t.Tty) != TYident && 1244 tybasic(t.Tty) != TYtemplate && 1245 tybasic(t.Tty) != TYmfunc && 1246 tybasic(t.Tty) != TYarray) 1247 printf(" Tsize=%lld", cast(long)type_size(t)); 1248 printf(" Tnext=%p",t.Tnext); 1249 switch (tybasic(t.Tty)) 1250 { case TYstruct: 1251 case TYmemptr: 1252 printf(" Ttag=%p,'%s'",t.Ttag,t.Ttag.Sident.ptr); 1253 //printf(" Sfldlst=%p",t.Ttag.Sstruct.Sfldlst); 1254 break; 1255 1256 case TYarray: 1257 printf(" Tdim=%lld", cast(long)t.Tdim); 1258 break; 1259 1260 case TYident: 1261 printf(" Tident='%s'",t.Tident); 1262 break; 1263 case TYtemplate: 1264 printf(" Tsym='%s'",(cast(typetemp_t *)t).Tsym.Sident.ptr); 1265 { 1266 int i; 1267 1268 i = 1; 1269 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext) 1270 { printf("\nTP%d (%p): ",i++,p); 1271 fflush(stdout); 1272 1273 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext); 1274 param_debug(p); 1275 if (p.Pident) 1276 printf("'%s' ", p.Pident); 1277 if (p.Ptype) 1278 type_print(p.Ptype); 1279 if (p.Pelem) 1280 elem_print(p.Pelem); 1281 } 1282 } 1283 break; 1284 1285 default: 1286 if (tyfunc(t.Tty)) 1287 { 1288 int i; 1289 1290 i = 1; 1291 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext) 1292 { printf("\nP%d (%p): ",i++,p); 1293 fflush(stdout); 1294 1295 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext); 1296 param_debug(p); 1297 if (p.Pident) 1298 printf("'%s' ", p.Pident); 1299 type_print(p.Ptype); 1300 } 1301 } 1302 break; 1303 } 1304 printf("\n"); 1305 if (t.Tnext) type_print(t.Tnext); 1306 } 1307 1308 /******************************* 1309 * Pretty-print a param_t 1310 */ 1311 1312 void param_t_print(const param_t* p) 1313 { 1314 printf("Pident=%p,Ptype=%p,Pelem=%p,Psym=%p,Pnext=%p\n",p.Pident,p.Ptype,p.Pelem,p.Psym,p.Pnext); 1315 if (p.Pident) 1316 printf("\tPident = '%s'\n", p.Pident); 1317 if (p.Ptype) 1318 { printf("\tPtype =\n"); 1319 type_print(p.Ptype); 1320 } 1321 if (p.Pelem) 1322 { printf("\tPelem =\n"); 1323 elem_print(p.Pelem); 1324 } 1325 if (p.Pdeftype) 1326 { printf("\tPdeftype =\n"); 1327 type_print(p.Pdeftype); 1328 } 1329 if (p.Psym) 1330 { printf("\tPsym = '%s'\n", p.Psym.Sident.ptr); 1331 } 1332 if (p.Pptpl) 1333 { printf("\tPptpl = %p\n", p.Pptpl); 1334 } 1335 } 1336 1337 void param_t_print_list(param_t* p) 1338 { 1339 for (; p; p = p.Pnext) 1340 p.print(); 1341 } 1342 1343 1344 /********************************** 1345 * Hydrate a type. 1346 */ 1347 1348 version (SCPP_HTOD) 1349 { 1350 1351 static if (HYDRATE) 1352 { 1353 void type_hydrate(type **pt) 1354 { 1355 type *t; 1356 1357 assert(pt); 1358 while (isdehydrated(*pt)) 1359 { 1360 t = cast(type *) ph_hydrate(cast(void**)pt); 1361 type_debug(t); 1362 switch (tybasic(t.Tty)) 1363 { 1364 case TYstruct: 1365 case TYenum: 1366 case TYmemptr: 1367 case TYvtshape: 1368 // Cannot assume symbol is hydrated, because entire HX file 1369 // may not have been hydrated. 1370 Classsym_hydrate(&t.Ttag); 1371 symbol_debug(t.Ttag); 1372 break; 1373 case TYident: 1374 ph_hydrate(cast(void**)&t.Tident); 1375 break; 1376 case TYtemplate: 1377 symbol_hydrate(&(cast(typetemp_t *)t).Tsym); 1378 param_hydrate(&t.Tparamtypes); 1379 break; 1380 case TYarray: 1381 if (t.Tflags & TFvla) 1382 el_hydrate(&t.Tel); 1383 break; 1384 default: 1385 if (tyfunc(t.Tty)) 1386 { param_hydrate(&t.Tparamtypes); 1387 list_hydrate(&t.Texcspec, cast(list_free_fp)&type_hydrate); 1388 } 1389 else if (t.Talternate && typtr(t.Tty)) 1390 type_hydrate(&t.Talternate); 1391 else if (t.Tkey && typtr(t.Tty)) 1392 type_hydrate(&t.Tkey); 1393 break; 1394 } 1395 pt = &t.Tnext; 1396 } 1397 } 1398 } 1399 1400 /********************************** 1401 * Dehydrate a type. 1402 */ 1403 1404 static if (DEHYDRATE) 1405 { 1406 void type_dehydrate(type **pt) 1407 { 1408 type *t; 1409 1410 while ((t = *pt) != null && !isdehydrated(t)) 1411 { 1412 ph_dehydrate(pt); 1413 version (DEBUG_XSYMGEN) 1414 { 1415 /* don't dehydrate types in HEAD when creating XSYM */ 1416 if (xsym_gen && (t.Tflags & TFhydrated)) 1417 return; 1418 } 1419 type_debug(t); 1420 switch (tybasic(t.Tty)) 1421 { 1422 case TYstruct: 1423 case TYenum: 1424 case TYmemptr: 1425 case TYvtshape: 1426 Classsym_dehydrate(&t.Ttag); 1427 break; 1428 case TYident: 1429 ph_dehydrate(&t.Tident); 1430 break; 1431 case TYtemplate: 1432 symbol_dehydrate(&(cast(typetemp_t *)t).Tsym); 1433 param_dehydrate(&t.Tparamtypes); 1434 break; 1435 case TYarray: 1436 if (t.Tflags & TFvla) 1437 el_dehydrate(&t.Tel); 1438 break; 1439 default: 1440 if (tyfunc(t.Tty)) 1441 { param_dehydrate(&t.Tparamtypes); 1442 list_dehydrate(&t.Texcspec, cast(list_free_fp)&type_dehydrate); 1443 } 1444 else if (t.Talternate && typtr(t.Tty)) 1445 type_dehydrate(&t.Talternate); 1446 else if (t.Tkey && typtr(t.Tty)) 1447 type_dehydrate(&t.Tkey); 1448 break; 1449 } 1450 pt = &t.Tnext; 1451 } 1452 } 1453 } 1454 1455 } 1456 1457 /**************************** 1458 * Allocate a param_t. 1459 */ 1460 1461 param_t *param_calloc() 1462 { 1463 static param_t pzero; 1464 param_t *p; 1465 1466 if (param_list) 1467 { 1468 p = param_list; 1469 param_list = p.Pnext; 1470 } 1471 else 1472 { 1473 p = cast(param_t *) mem_fmalloc(param_t.sizeof); 1474 } 1475 *p = pzero; 1476 1477 debug p.id = param_t.IDparam; 1478 1479 return p; 1480 } 1481 1482 /*************************** 1483 * Allocate a param_t of type t, and append it to parameter list. 1484 */ 1485 1486 param_t *param_append_type(param_t **pp,type *t) 1487 { param_t *p; 1488 1489 p = param_calloc(); 1490 while (*pp) 1491 { param_debug(*pp); 1492 pp = &((*pp).Pnext); /* find end of list */ 1493 } 1494 *pp = p; /* append p to list */ 1495 type_debug(t); 1496 p.Ptype = t; 1497 t.Tcount++; 1498 return p; 1499 } 1500 1501 /************************ 1502 * Version of param_free() suitable for list_free(). 1503 */ 1504 1505 void param_free_l(param_t *p) 1506 { 1507 param_free(&p); 1508 } 1509 1510 /*********************** 1511 * Free parameter list. 1512 * Output: 1513 * paramlst = null 1514 */ 1515 1516 void param_free(param_t **pparamlst) 1517 { param_t* p,pn; 1518 1519 //debug_assert(PARSER); 1520 for (p = *pparamlst; p; p = pn) 1521 { param_debug(p); 1522 pn = p.Pnext; 1523 type_free(p.Ptype); 1524 mem_free(p.Pident); 1525 el_free(p.Pelem); 1526 type_free(p.Pdeftype); 1527 if (p.Pptpl) 1528 param_free(&p.Pptpl); 1529 1530 debug p.id = 0; 1531 1532 p.Pnext = param_list; 1533 param_list = p; 1534 } 1535 *pparamlst = null; 1536 } 1537 1538 /*********************************** 1539 * Compute number of parameters 1540 */ 1541 1542 uint param_t_length(param_t* p) 1543 { 1544 uint nparams = 0; 1545 1546 for (; p; p = p.Pnext) 1547 nparams++; 1548 return nparams; 1549 } 1550 1551 /************************************* 1552 * Create template-argument-list blank from 1553 * template-parameter-list 1554 * Input: 1555 * ptali initial template-argument-list 1556 */ 1557 1558 param_t *param_t_createTal(param_t* p, param_t *ptali) 1559 { 1560 version (SCPP_HTOD) 1561 { 1562 param_t *ptalistart = ptali; 1563 param_t *pstart = p; 1564 } 1565 param_t *ptal = null; 1566 param_t **pp = &ptal; 1567 1568 for (; p; p = p.Pnext) 1569 { 1570 *pp = param_calloc(); 1571 if (p.Pident) 1572 { 1573 // Should find a way to just point rather than dup 1574 (*pp).Pident = cast(char *)MEM_PH_STRDUP(p.Pident); 1575 } 1576 if (ptali) 1577 { 1578 if (ptali.Ptype) 1579 { (*pp).Ptype = ptali.Ptype; 1580 (*pp).Ptype.Tcount++; 1581 } 1582 if (ptali.Pelem) 1583 { 1584 elem *e = el_copytree(ptali.Pelem); 1585 version (SCPP_HTOD) 1586 { 1587 if (p.Ptype) 1588 { type *t = p.Ptype; 1589 t = template_tyident(t, ptalistart, pstart, 1); 1590 e = poptelem3(typechk(e, t)); 1591 type_free(t); 1592 } 1593 } 1594 (*pp).Pelem = e; 1595 } 1596 (*pp).Psym = ptali.Psym; 1597 (*pp).Pflags = ptali.Pflags; 1598 assert(!ptali.Pptpl); 1599 ptali = ptali.Pnext; 1600 } 1601 pp = &(*pp).Pnext; 1602 } 1603 return ptal; 1604 } 1605 1606 /********************************** 1607 * Look for Pident matching id 1608 */ 1609 1610 param_t *param_t_search(param_t* p, char *id) 1611 { 1612 for (; p; p = p.Pnext) 1613 { 1614 if (p.Pident && strcmp(p.Pident, id) == 0) 1615 break; 1616 } 1617 return p; 1618 } 1619 1620 /********************************** 1621 * Look for Pident matching id 1622 */ 1623 1624 int param_t_searchn(param_t* p, char *id) 1625 { 1626 int n = 0; 1627 1628 for (; p; p = p.Pnext) 1629 { 1630 if (p.Pident && strcmp(p.Pident, id) == 0) 1631 return n; 1632 n++; 1633 } 1634 return -1; 1635 } 1636 1637 /************************************* 1638 * Search for member, create symbol as needed. 1639 * Used for symbol tables for VLA's such as: 1640 * void func(int n, int a[n]); 1641 */ 1642 1643 Symbol *param_search(const(char)* name, param_t **pp) 1644 { Symbol *s = null; 1645 param_t *p; 1646 1647 p = (*pp).search(cast(char *)name); 1648 if (p) 1649 { 1650 s = p.Psym; 1651 if (!s) 1652 { 1653 s = symbol_calloc(p.Pident); 1654 s.Sclass = SCparameter; 1655 s.Stype = p.Ptype; 1656 s.Stype.Tcount++; 1657 p.Psym = s; 1658 } 1659 } 1660 return s; 1661 } 1662 1663 /********************************** 1664 * Hydrate/dehydrate a type. 1665 */ 1666 1667 version (SCPP_HTOD) 1668 { 1669 static if (HYDRATE) 1670 { 1671 void param_hydrate(param_t **pp) 1672 { 1673 param_t *p; 1674 1675 assert(pp); 1676 if (isdehydrated(*pp)) 1677 { while (*pp) 1678 { assert(isdehydrated(*pp)); 1679 p = cast(param_t *) ph_hydrate(cast(void**)pp); 1680 param_debug(p); 1681 1682 type_hydrate(&p.Ptype); 1683 if (p.Ptype) 1684 type_debug(p.Ptype); 1685 ph_hydrate(cast(void**)&p.Pident); 1686 if (CPP) 1687 { 1688 el_hydrate(&p.Pelem); 1689 if (p.Pelem) 1690 elem_debug(p.Pelem); 1691 type_hydrate(&p.Pdeftype); 1692 if (p.Pptpl) 1693 param_hydrate(&p.Pptpl); 1694 if (p.Psym) 1695 symbol_hydrate(&p.Psym); 1696 if (p.PelemToken) 1697 token_hydrate(&p.PelemToken); 1698 } 1699 1700 pp = &p.Pnext; 1701 } 1702 } 1703 } 1704 } 1705 1706 static if (DEHYDRATE) 1707 { 1708 void param_dehydrate(param_t **pp) 1709 { 1710 param_t *p; 1711 1712 assert(pp); 1713 while ((p = *pp) != null && !isdehydrated(p)) 1714 { param_debug(p); 1715 1716 ph_dehydrate(pp); 1717 if (p.Ptype && !isdehydrated(p.Ptype)) 1718 type_debug(p.Ptype); 1719 type_dehydrate(&p.Ptype); 1720 ph_dehydrate(&p.Pident); 1721 if (CPP) 1722 { 1723 el_dehydrate(&p.Pelem); 1724 type_dehydrate(&p.Pdeftype); 1725 if (p.Pptpl) 1726 param_dehydrate(&p.Pptpl); 1727 if (p.Psym) 1728 symbol_dehydrate(&p.Psym); 1729 if (p.PelemToken) 1730 token_dehydrate(&p.PelemToken); 1731 } 1732 pp = &p.Pnext; 1733 } 1734 } 1735 } 1736 } 1737 1738 version (MARS) 1739 { 1740 1741 int typematch(type *t1, type *t2, int relax); 1742 1743 // Return TRUE if type lists match. 1744 private int paramlstmatch(param_t *p1,param_t *p2) 1745 { 1746 return p1 == p2 || 1747 p1 && p2 && typematch(p1.Ptype,p2.Ptype,0) && 1748 paramlstmatch(p1.Pnext,p2.Pnext) 1749 ; 1750 } 1751 1752 /************************************************* 1753 * A cheap version of exp2.typematch() and exp2.paramlstmatch(), 1754 * so that we can get cpp_mangle() to work for MARS. 1755 * It's less complex because it doesn't do templates and 1756 * can rely on strict typechecking. 1757 * Returns: 1758 * !=0 if types match. 1759 */ 1760 1761 int typematch(type *t1,type *t2,int relax) 1762 { tym_t t1ty, t2ty; 1763 tym_t tym; 1764 1765 tym = ~(mTYimport | mTYnaked); 1766 1767 return t1 == t2 || 1768 t1 && t2 && 1769 1770 ( 1771 /* ignore name mangling */ 1772 (t1ty = (t1.Tty & tym)) == (t2ty = (t2.Tty & tym)) 1773 ) 1774 && 1775 1776 (tybasic(t1ty) != TYarray || t1.Tdim == t2.Tdim || 1777 t1.Tflags & TFsizeunknown || t2.Tflags & TFsizeunknown) 1778 && 1779 1780 (tybasic(t1ty) != TYstruct 1781 && tybasic(t1ty) != TYenum 1782 && tybasic(t1ty) != TYmemptr 1783 || t1.Ttag == t2.Ttag) 1784 && 1785 1786 typematch(t1.Tnext,t2.Tnext, 0) 1787 && 1788 1789 (!tyfunc(t1ty) || 1790 ((t1.Tflags & TFfixed) == (t2.Tflags & TFfixed) && 1791 paramlstmatch(t1.Tparamtypes,t2.Tparamtypes) )) 1792 ; 1793 } 1794 1795 } 1796 1797 }