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 import core.stdc.stdio; 15 import core.stdc.stdlib; 16 import core.stdc.string; 17 18 import dmd.backend.cdef; 19 import dmd.backend.cc; 20 import dmd.backend.dlist; 21 import dmd.backend.el; 22 import dmd.backend.global; 23 import dmd.backend.mem; 24 import dmd.backend.oper; 25 import dmd.backend.ty; 26 import dmd.backend.type; 27 28 29 nothrow: 30 @safe: 31 32 @trusted 33 struct_t* struct_calloc() { return cast(struct_t*) mem_calloc(struct_t.sizeof); } 34 35 private __gshared 36 { 37 type *type_list; // free list of types 38 param_t *param_list; // free list of params 39 40 int type_num,type_max; /* gather statistics on # of types */ 41 } 42 43 __gshared 44 { 45 type*[TYMAX] tstypes; 46 type*[TYMAX] tsptr2types; 47 48 type* tstrace,tsclib,tsjlib,tsdlib, 49 tslogical; 50 type* tspvoid,tspcvoid; 51 type* tsptrdiff, tssize; 52 } 53 54 /*********************** 55 * Compute size of type in bytes. 56 * Params: 57 * t = type 58 * Returns: 59 * size 60 */ 61 @trusted @nogc 62 targ_size_t type_size(const type *t) 63 { targ_size_t s; 64 tym_t tyb; 65 66 type_debug(t); 67 tyb = tybasic(t.Tty); 68 69 debug if (tyb >= TYMAX) 70 /*type_print(t),*/ 71 printf("tyb = x%x\n", tyb); 72 73 assert(tyb < TYMAX); 74 s = _tysize[tyb]; 75 if (s == cast(targ_size_t) -1) 76 { 77 switch (tyb) 78 { 79 // in case program plays games with function pointers 80 case TYffunc: 81 case TYfpfunc: 82 case TYfsfunc: 83 case TYf16func: 84 case TYhfunc: 85 case TYnfunc: /* in case program plays games with function pointers */ 86 case TYnpfunc: 87 case TYnsfunc: 88 case TYifunc: 89 case TYjfunc: 90 s = 1; 91 break; 92 case TYarray: 93 { 94 if (t.Tflags & TFsizeunknown) 95 { 96 } 97 if (t.Tflags & TFvla) 98 { 99 s = _tysize[pointertype]; 100 break; 101 } 102 s = type_size(t.Tnext); 103 uint u = cast(uint)t.Tdim * cast(uint) s; 104 if (t.Tdim && ((u / t.Tdim) != s || cast(int)u < 0)) 105 assert(0); // overflow should have been detected in front end 106 s = u; 107 break; 108 } 109 case TYstruct: 110 { 111 auto ts = t.Ttag.Stype; // find main instance 112 // (for const struct X) 113 assert(ts.Ttag); 114 s = ts.Ttag.Sstruct.Sstructsize; 115 break; 116 } 117 case TYvoid: 118 s = 1; 119 break; 120 121 case TYref: 122 s = tysize(TYnptr); 123 break; 124 125 default: 126 debug printf("%s\n", tym_str(t.Tty)); 127 assert(0); 128 } 129 } 130 return s; 131 } 132 133 /******************************** 134 * Return the size of a type for alignment purposes. 135 */ 136 137 @trusted 138 uint type_alignsize(type *t) 139 { targ_size_t sz; 140 141 L1: 142 type_debug(t); 143 144 sz = tyalignsize(t.Tty); 145 if (sz == cast(targ_size_t)-1) 146 { 147 switch (tybasic(t.Tty)) 148 { 149 case TYarray: 150 if (t.Tflags & TFsizeunknown) 151 goto err1; 152 t = t.Tnext; 153 goto L1; 154 case TYstruct: 155 t = t.Ttag.Stype; // find main instance 156 // (for const struct X) 157 if (t.Tflags & TFsizeunknown) 158 goto err1; 159 sz = t.Ttag.Sstruct.Salignsize; 160 if (sz > t.Ttag.Sstruct.Sstructalign + 1) 161 sz = t.Ttag.Sstruct.Sstructalign + 1; 162 break; 163 164 case TYldouble: 165 assert(0); 166 167 case TYcdouble: 168 sz = 8; // not 16 169 break; 170 171 default: 172 err1: // let type_size() handle error messages 173 sz = type_size(t); 174 break; 175 } 176 } 177 178 //printf("type_alignsize() = %d\n", sz); 179 return cast(uint)sz; 180 } 181 182 /*********************************** 183 * Compute special zero sized struct. 184 * Params: 185 * t = type of parameter 186 * tyf = function type 187 * Returns: 188 * true if it is 189 */ 190 @trusted 191 bool type_zeroSize(type *t, tym_t tyf) 192 { 193 if (tyf != TYjfunc && config.exe & (EX_FREEBSD | EX_OPENBSD | EX_OSX)) 194 { 195 /* Use clang convention for 0 size structs 196 */ 197 if (t && tybasic(t.Tty) == TYstruct) 198 { 199 type *ts = t.Ttag.Stype; // find main instance 200 // (for const struct X) 201 if (ts.Tflags & TFsizeunknown) 202 { 203 } 204 if (ts.Ttag.Sstruct.Sflags & STR0size) 205 //{ printf("0size\n"); type_print(t); *(char*)0=0; 206 return true; 207 //} 208 } 209 } 210 return false; 211 } 212 213 /********************************* 214 * Compute the size of a single parameter. 215 * Params: 216 * t = type of parameter 217 * tyf = function type 218 * Returns: 219 * size in bytes 220 */ 221 uint type_parameterSize(type *t, tym_t tyf) 222 { 223 if (type_zeroSize(t, tyf)) 224 return 0; 225 return cast(uint)type_size(t); 226 } 227 228 /***************************** 229 * Compute the total size of parameters for function call. 230 * Used for stdcall name mangling. 231 * Note that hidden parameters do not contribute to size. 232 * Params: 233 * t = function type 234 * Returns: 235 * total stack usage in bytes 236 */ 237 238 @trusted 239 uint type_paramsize(type *t) 240 { 241 targ_size_t sz = 0; 242 if (tyfunc(t.Tty)) 243 { 244 for (param_t *p = t.Tparamtypes; p; p = p.Pnext) 245 { 246 const size_t n = type_parameterSize(p.Ptype, tybasic(t.Tty)); 247 sz += _align(REGSIZE,n); // align to REGSIZE boundary 248 } 249 } 250 return cast(uint)sz; 251 } 252 253 /***************************** 254 * Create a type & initialize it. 255 * Input: 256 * ty = TYxxxx 257 * Returns: 258 * pointer to newly created type. 259 */ 260 261 @trusted @nogc 262 type *type_alloc(tym_t ty) 263 { type *t; 264 265 assert(tybasic(ty) != TYtemplate); 266 if (type_list) 267 { t = type_list; 268 type_list = t.Tnext; 269 } 270 else 271 t = cast(type *) mem_fmalloc(type.sizeof); 272 *t = type(); 273 t.Tty = ty; 274 version (SRCPOS_4TYPES) 275 { 276 if (PARSER && config.fulltypes) 277 t.Tsrcpos = getlinnum(); 278 } 279 debug 280 { 281 t.id = type.IDtype; 282 type_num++; 283 if (type_num > type_max) 284 type_max = type_num; 285 } 286 //printf("type_alloc() = %p %s\n", t, tym_str(t.Tty)); 287 //if (t == (type*)0xB6B744) *(char*)0=0; 288 return t; 289 } 290 291 /***************************** 292 * Fake a type & initialize it. 293 * Input: 294 * ty = TYxxxx 295 * Returns: 296 * pointer to newly created type. 297 */ 298 @nogc 299 type *type_fake(tym_t ty) 300 { type *t; 301 302 assert(ty != TYstruct); 303 304 t = type_alloc(ty); 305 if (typtr(ty) || tyfunc(ty)) 306 { t.Tnext = type_alloc(TYvoid); /* fake with pointer to void */ 307 t.Tnext.Tcount = 1; 308 } 309 return t; 310 } 311 312 /***************************** 313 * Allocate a type of ty with a Tnext of tn. 314 */ 315 316 type *type_allocn(tym_t ty,type *tn) 317 { type *t; 318 319 //printf("type_allocn(ty = x%x, tn = %p)\n", ty, tn); 320 assert(tn); 321 type_debug(tn); 322 t = type_alloc(ty); 323 t.Tnext = tn; 324 tn.Tcount++; 325 //printf("\tt = %p\n", t); 326 return t; 327 } 328 329 /******************************** 330 * Allocate a pointer type. 331 * Returns: 332 * Tcount already incremented 333 */ 334 335 type *type_pointer(type *tnext) 336 { 337 type *t = type_allocn(TYnptr, tnext); 338 t.Tcount++; 339 return t; 340 } 341 342 /******************************** 343 * Allocate a dynamic array type. 344 * Returns: 345 * Tcount already incremented 346 */ 347 @trusted 348 type *type_dyn_array(type *tnext) 349 { 350 type *t = type_allocn(TYdarray, tnext); 351 t.Tcount++; 352 return t; 353 } 354 355 /******************************** 356 * Allocate a static array type. 357 * Returns: 358 * Tcount already incremented 359 */ 360 361 extern (C) type *type_static_array(targ_size_t dim, type *tnext) 362 { 363 type *t = type_allocn(TYarray, tnext); 364 t.Tdim = dim; 365 t.Tcount++; 366 return t; 367 } 368 369 /******************************** 370 * Allocate an associative array type, 371 * which are key=value pairs 372 * Returns: 373 * Tcount already incremented 374 */ 375 376 @trusted 377 type *type_assoc_array(type *tkey, type *tvalue) 378 { 379 type *t = type_allocn(TYaarray, tvalue); 380 t.Tkey = tkey; 381 tkey.Tcount++; 382 t.Tcount++; 383 return t; 384 } 385 386 /******************************** 387 * Allocate a delegate type. 388 * Returns: 389 * Tcount already incremented 390 */ 391 392 @trusted 393 type *type_delegate(type *tnext) 394 { 395 type *t = type_allocn(TYdelegate, tnext); 396 t.Tcount++; 397 return t; 398 } 399 400 /*********************************** 401 * Allocation a function type. 402 * Params: 403 * tyf = function type 404 * ptypes = types of the function parameters 405 * variadic = if ... function 406 * tret = return type 407 * Returns: 408 * Tcount already incremented 409 */ 410 @trusted 411 extern (C) 412 type *type_function(tym_t tyf, type*[] ptypes, bool variadic, type *tret) 413 { 414 param_t *paramtypes = null; 415 foreach (p; ptypes) 416 { 417 param_append_type(¶mtypes, p); 418 } 419 type *t = type_allocn(tyf, tret); 420 t.Tflags |= TFprototype; 421 if (!variadic) 422 t.Tflags |= TFfixed; 423 t.Tparamtypes = paramtypes; 424 t.Tcount++; 425 return t; 426 } 427 428 /*************************************** 429 * Create an enum type. 430 * Input: 431 * name name of enum 432 * tbase "base" type of enum 433 * Returns: 434 * Tcount already incremented 435 */ 436 @trusted 437 type *type_enum(const(char)* name, type *tbase) 438 { 439 Symbol *s = symbol_calloc(name[0 .. strlen(name)]); 440 s.Sclass = SC.enum_; 441 s.Senum = cast(enum_t *) mem_calloc(enum_t.sizeof); 442 s.Senum.SEflags |= SENforward; // forward reference 443 444 type *t = type_allocn(TYenum, tbase); 445 t.Ttag = cast(Classsym *)s; // enum tag name 446 t.Tcount++; 447 s.Stype = t; 448 t.Tcount++; 449 return t; 450 } 451 452 /************************************** 453 * Create a struct/union/class type. 454 * Params: 455 * name = name of struct (this function makes its own copy of the string) 456 * is0size = if struct has no fields (even if Sstructsize is 1) 457 * Returns: 458 * Tcount already incremented 459 */ 460 @trusted 461 type *type_struct_class(const(char)* name, uint alignsize, uint structsize, 462 type *arg1type, type *arg2type, bool isUnion, bool isClass, bool isPOD, bool is0size) 463 { 464 static if (0) 465 { 466 printf("type_struct_class(%s, %p, %p)\n", name, arg1type, arg2type); 467 if (arg1type) 468 { 469 printf("arg1type:\n"); 470 type_print(arg1type); 471 } 472 if (arg2type) 473 { 474 printf("arg2type:\n"); 475 type_print(arg2type); 476 } 477 } 478 Symbol *s = symbol_calloc(name[0 .. strlen(name)]); 479 s.Sclass = SC.struct_; 480 s.Sstruct = struct_calloc(); 481 s.Sstruct.Salignsize = alignsize; 482 s.Sstruct.Sstructalign = cast(ubyte)alignsize; 483 s.Sstruct.Sstructsize = structsize; 484 s.Sstruct.Sarg1type = arg1type; 485 s.Sstruct.Sarg2type = arg2type; 486 487 if (!isPOD) 488 s.Sstruct.Sflags |= STRnotpod; 489 if (isUnion) 490 s.Sstruct.Sflags |= STRunion; 491 if (isClass) 492 { s.Sstruct.Sflags |= STRclass; 493 assert(!isUnion && isPOD); 494 } 495 if (is0size) 496 s.Sstruct.Sflags |= STR0size; 497 498 type *t = type_alloc(TYstruct); 499 t.Ttag = cast(Classsym *)s; // structure tag name 500 t.Tcount++; 501 s.Stype = t; 502 t.Tcount++; 503 return t; 504 } 505 506 /***************************** 507 * Free up data type. 508 */ 509 510 @trusted 511 void type_free(type *t) 512 { type *tn; 513 tym_t ty; 514 515 while (t) 516 { 517 //printf("type_free(%p, Tcount = %d)\n", t, t.Tcount); 518 type_debug(t); 519 assert(cast(int)t.Tcount != -1); 520 if (--t.Tcount) /* if usage count doesn't go to 0 */ 521 break; 522 ty = tybasic(t.Tty); 523 if (tyfunc(ty)) 524 { param_free(&t.Tparamtypes); 525 list_free(&t.Texcspec, cast(list_free_fp)&type_free); 526 goto L1; 527 } 528 if (t.Tflags & TFvla && t.Tel) 529 { 530 el_free(t.Tel); 531 goto L1; 532 } 533 if (t.Tkey && typtr(ty)) 534 type_free(t.Tkey); 535 L1: 536 537 debug 538 { 539 type_num--; 540 //printf("Free'ing type %p %s\n", t, tym_str(t.Tty)); 541 t.id = 0; /* no longer a valid type */ 542 } 543 544 tn = t.Tnext; 545 t.Tnext = type_list; 546 type_list = t; /* link into free list */ 547 t = tn; 548 } 549 } 550 551 version (STATS) 552 { 553 /* count number of free types available on type list */ 554 void type_count_free() 555 { 556 type *t; 557 int count; 558 559 for(t=type_list;t;t=t.Tnext) 560 count++; 561 printf("types on free list %d with max of %d\n",count,type_max); 562 } 563 } 564 565 /********************************** 566 * Initialize type package. 567 */ 568 569 private type * type_allocbasic(tym_t ty) 570 { type *t; 571 572 t = type_alloc(ty); 573 t.Tmangle = mTYman_c; 574 t.Tcount = 1; /* so it is not inadvertently free'd */ 575 return t; 576 } 577 578 @trusted 579 void type_init() 580 { 581 tstypes[TYbool] = type_allocbasic(TYbool); 582 tstypes[TYwchar_t] = type_allocbasic(TYwchar_t); 583 tstypes[TYdchar] = type_allocbasic(TYdchar); 584 tstypes[TYvoid] = type_allocbasic(TYvoid); 585 tstypes[TYnullptr] = type_allocbasic(TYnullptr); 586 tstypes[TYchar16] = type_allocbasic(TYchar16); 587 tstypes[TYuchar] = type_allocbasic(TYuchar); 588 tstypes[TYschar] = type_allocbasic(TYschar); 589 tstypes[TYchar] = type_allocbasic(TYchar); 590 tstypes[TYshort] = type_allocbasic(TYshort); 591 tstypes[TYushort] = type_allocbasic(TYushort); 592 tstypes[TYint] = type_allocbasic(TYint); 593 tstypes[TYuint] = type_allocbasic(TYuint); 594 tstypes[TYlong] = type_allocbasic(TYlong); 595 tstypes[TYulong] = type_allocbasic(TYulong); 596 tstypes[TYllong] = type_allocbasic(TYllong); 597 tstypes[TYullong] = type_allocbasic(TYullong); 598 tstypes[TYfloat] = type_allocbasic(TYfloat); 599 tstypes[TYdouble] = type_allocbasic(TYdouble); 600 tstypes[TYdouble_alias] = type_allocbasic(TYdouble_alias); 601 tstypes[TYldouble] = type_allocbasic(TYldouble); 602 tstypes[TYifloat] = type_allocbasic(TYifloat); 603 tstypes[TYidouble] = type_allocbasic(TYidouble); 604 tstypes[TYildouble] = type_allocbasic(TYildouble); 605 tstypes[TYcfloat] = type_allocbasic(TYcfloat); 606 tstypes[TYcdouble] = type_allocbasic(TYcdouble); 607 tstypes[TYcldouble] = type_allocbasic(TYcldouble); 608 609 if (I64) 610 { 611 TYptrdiff = TYllong; 612 TYsize = TYullong; 613 tsptrdiff = tstypes[TYllong]; 614 tssize = tstypes[TYullong]; 615 } 616 else 617 { 618 TYptrdiff = TYint; 619 TYsize = TYuint; 620 tsptrdiff = tstypes[TYint]; 621 tssize = tstypes[TYuint]; 622 } 623 624 // Type of trace function 625 tstrace = type_fake(I16 ? TYffunc : TYnfunc); 626 tstrace.Tmangle = mTYman_c; 627 tstrace.Tcount++; 628 629 chartype = (config.flags3 & CFG3ju) ? tstypes[TYuchar] : tstypes[TYchar]; 630 631 // Type of far library function 632 tsclib = type_fake(LARGECODE ? TYfpfunc : TYnpfunc); 633 tsclib.Tmangle = mTYman_c; 634 tsclib.Tcount++; 635 636 tspvoid = type_allocn(pointertype,tstypes[TYvoid]); 637 tspvoid.Tmangle = mTYman_c; 638 tspvoid.Tcount++; 639 640 // Type of far library function 641 tsjlib = type_fake(TYjfunc); 642 tsjlib.Tmangle = mTYman_c; 643 tsjlib.Tcount++; 644 645 tsdlib = tsjlib; 646 647 // Type of logical expression 648 tslogical = (config.flags4 & CFG4bool) ? tstypes[TYbool] : tstypes[TYint]; 649 650 for (int i = 0; i < TYMAX; i++) 651 { 652 if (tstypes[i]) 653 { tsptr2types[i] = type_allocn(pointertype,tstypes[i]); 654 tsptr2types[i].Tcount++; 655 } 656 } 657 } 658 659 /********************************** 660 * Free type_list. 661 */ 662 663 void type_term() 664 { 665 static if (TERMCODE) 666 { 667 type *tn; 668 param_t *pn; 669 int i; 670 671 for (i = 0; i < tstypes.length; i++) 672 { type *t = tsptr2types[i]; 673 674 if (t) 675 { assert(!(t.Tty & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 676 assert(!(t.Tflags)); 677 assert(!(t.Tmangle)); 678 type_free(t); 679 } 680 type_free(tstypes[i]); 681 } 682 683 type_free(tsclib); 684 type_free(tspvoid); 685 type_free(tspcvoid); 686 type_free(tsjlib); 687 type_free(tstrace); 688 689 while (type_list) 690 { tn = type_list.Tnext; 691 mem_ffree(type_list); 692 type_list = tn; 693 } 694 695 while (param_list) 696 { pn = param_list.Pnext; 697 mem_ffree(param_list); 698 param_list = pn; 699 } 700 701 debug 702 { 703 printf("Max # of types = %d\n",type_max); 704 if (type_num != 0) 705 printf("type_num = %d\n",type_num); 706 /* assert(type_num == 0);*/ 707 } 708 709 } 710 } 711 712 /******************************* 713 * Type type information. 714 */ 715 716 /************************** 717 * Make copy of a type. 718 */ 719 720 @trusted 721 type *type_copy(type *t) 722 { type *tn; 723 param_t *p; 724 725 type_debug(t); 726 tn = type_alloc(t.Tty); 727 728 *tn = *t; 729 switch (tybasic(tn.Tty)) 730 { 731 case TYarray: 732 if (tn.Tflags & TFvla) 733 tn.Tel = el_copytree(tn.Tel); 734 break; 735 736 default: 737 if (tyfunc(tn.Tty)) 738 { 739 tn.Tparamtypes = null; 740 for (p = t.Tparamtypes; p; p = p.Pnext) 741 { param_t *pn; 742 743 pn = param_append_type(&tn.Tparamtypes,p.Ptype); 744 if (p.Pident) 745 { 746 pn.Pident = cast(char *)mem_strdup(p.Pident); 747 } 748 assert(!p.Pelem); 749 } 750 } 751 else 752 { 753 if (tn.Tkey && typtr(tn.Tty)) 754 tn.Tkey.Tcount++; 755 } 756 break; 757 } 758 if (tn.Tnext) 759 { type_debug(tn.Tnext); 760 tn.Tnext.Tcount++; 761 } 762 tn.Tcount = 0; 763 return tn; 764 } 765 766 /**************************** 767 * Modify the tym_t field of a type. 768 */ 769 770 type *type_setty(type **pt,uint newty) 771 { type *t; 772 773 t = *pt; 774 type_debug(t); 775 if (cast(tym_t)newty != t.Tty) 776 { if (t.Tcount > 1) /* if other people pointing at t */ 777 { type *tn; 778 779 tn = type_copy(t); 780 tn.Tcount++; 781 type_free(t); 782 t = tn; 783 *pt = t; 784 } 785 t.Tty = newty; 786 } 787 return t; 788 } 789 790 /****************************** 791 * Set type field of some object to t. 792 */ 793 794 type *type_settype(type **pt, type *t) 795 { 796 if (t) 797 { type_debug(t); 798 t.Tcount++; 799 } 800 type_free(*pt); 801 return *pt = t; 802 } 803 804 /**************************** 805 * Modify the Tmangle field of a type. 806 */ 807 808 type *type_setmangle(type **pt,mangle_t mangle) 809 { type *t; 810 811 t = *pt; 812 type_debug(t); 813 if (mangle != type_mangle(t)) 814 { 815 if (t.Tcount > 1) // if other people pointing at t 816 { type *tn; 817 818 tn = type_copy(t); 819 tn.Tcount++; 820 type_free(t); 821 t = tn; 822 *pt = t; 823 } 824 t.Tmangle = mangle; 825 } 826 return t; 827 } 828 829 /****************************** 830 * Set/clear const and volatile bits in *pt according to the settings 831 * in cv. 832 */ 833 834 type *type_setcv(type **pt,tym_t cv) 835 { uint ty; 836 837 type_debug(*pt); 838 ty = (*pt).Tty & ~(mTYconst | mTYvolatile | mTYimmutable | mTYshared); 839 return type_setty(pt,ty | (cv & (mTYconst | mTYvolatile | mTYimmutable | mTYshared))); 840 } 841 842 /***************************** 843 * Set dimension of array. 844 */ 845 846 type *type_setdim(type **pt,targ_size_t dim) 847 { type *t = *pt; 848 849 type_debug(t); 850 if (t.Tcount > 1) /* if other people pointing at t */ 851 { type *tn; 852 853 tn = type_copy(t); 854 tn.Tcount++; 855 type_free(t); 856 t = tn; 857 } 858 t.Tflags &= ~TFsizeunknown; /* we have determined its size */ 859 t.Tdim = dim; /* index of array */ 860 return *pt = t; 861 } 862 863 864 /***************************** 865 * Create a 'dependent' version of type t. 866 */ 867 868 type *type_setdependent(type *t) 869 { 870 type_debug(t); 871 if (t.Tcount > 0 && /* if other people pointing at t */ 872 !(t.Tflags & TFdependent)) 873 { 874 t = type_copy(t); 875 } 876 t.Tflags |= TFdependent; 877 return t; 878 } 879 880 /************************************ 881 * Determine if type t is a dependent type. 882 */ 883 884 @trusted 885 int type_isdependent(type *t) 886 { 887 Symbol *stempl; 888 type *tstart; 889 890 //printf("type_isdependent(%p)\n", t); 891 //type_print(t); 892 for (tstart = t; t; t = t.Tnext) 893 { 894 type_debug(t); 895 if (t.Tflags & TFdependent) 896 goto Lisdependent; 897 if (tyfunc(t.Tty) 898 || tybasic(t.Tty) == TYtemplate 899 ) 900 { 901 for (param_t *p = t.Tparamtypes; p; p = p.Pnext) 902 { 903 if (p.Ptype && type_isdependent(p.Ptype)) 904 goto Lisdependent; 905 if (p.Pelem && el_isdependent(p.Pelem)) 906 goto Lisdependent; 907 } 908 } 909 else if (type_struct(t) && 910 (stempl = t.Ttag.Sstruct.Stempsym) != null) 911 { 912 for (param_t *p = t.Ttag.Sstruct.Sarglist; p; p = p.Pnext) 913 { 914 if (p.Ptype && type_isdependent(p.Ptype)) 915 goto Lisdependent; 916 if (p.Pelem && el_isdependent(p.Pelem)) 917 goto Lisdependent; 918 } 919 } 920 } 921 //printf("\tis not dependent\n"); 922 return 0; 923 924 Lisdependent: 925 //printf("\tis dependent\n"); 926 // Dependence on a dependent type makes this type dependent as well 927 tstart.Tflags |= TFdependent; 928 return 1; 929 } 930 931 932 /******************************* 933 * Recursively check if type u is embedded in type t. 934 * Returns: 935 * != 0 if embedded 936 */ 937 938 @trusted 939 int type_embed(type *t,type *u) 940 { param_t *p; 941 942 for (; t; t = t.Tnext) 943 { 944 type_debug(t); 945 if (t == u) 946 return 1; 947 if (tyfunc(t.Tty)) 948 { 949 for (p = t.Tparamtypes; p; p = p.Pnext) 950 if (type_embed(p.Ptype,u)) 951 return 1; 952 } 953 } 954 return 0; 955 } 956 957 958 /*********************************** 959 * Determine if type is a VLA. 960 */ 961 962 int type_isvla(type *t) 963 { 964 while (t) 965 { 966 if (tybasic(t.Tty) != TYarray) 967 break; 968 if (t.Tflags & TFvla) 969 return 1; 970 t = t.Tnext; 971 } 972 return 0; 973 } 974 975 976 /********************************** 977 * Pretty-print a type. 978 */ 979 980 @trusted 981 void type_print(const type *t) 982 { 983 type_debug(t); 984 printf("Tty=%s", tym_str(t.Tty)); 985 printf(" Tmangle=%d",t.Tmangle); 986 printf(" Tflags=x%x",t.Tflags); 987 printf(" Tcount=%d",t.Tcount); 988 if (!(t.Tflags & TFsizeunknown) && 989 tybasic(t.Tty) != TYvoid && 990 tybasic(t.Tty) != TYident && 991 tybasic(t.Tty) != TYtemplate && 992 tybasic(t.Tty) != TYmfunc && 993 tybasic(t.Tty) != TYarray) 994 printf(" Tsize=%lld", cast(long)type_size(t)); 995 printf(" Tnext=%p",t.Tnext); 996 switch (tybasic(t.Tty)) 997 { case TYstruct: 998 case TYmemptr: 999 printf(" Ttag=%p,'%s'",t.Ttag,t.Ttag.Sident.ptr); 1000 //printf(" Sfldlst=%p",t.Ttag.Sstruct.Sfldlst); 1001 break; 1002 1003 case TYarray: 1004 printf(" Tdim=%lld", cast(long)t.Tdim); 1005 break; 1006 1007 case TYident: 1008 printf(" Tident='%s'",t.Tident); 1009 break; 1010 case TYtemplate: 1011 printf(" Tsym='%s'",(cast(typetemp_t *)t).Tsym.Sident.ptr); 1012 { 1013 int i; 1014 1015 i = 1; 1016 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext) 1017 { printf("\nTP%d (%p): ",i++,p); 1018 fflush(stdout); 1019 1020 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext); 1021 param_debug(p); 1022 if (p.Pident) 1023 printf("'%s' ", p.Pident); 1024 if (p.Ptype) 1025 type_print(p.Ptype); 1026 if (p.Pelem) 1027 elem_print(p.Pelem); 1028 } 1029 } 1030 break; 1031 1032 default: 1033 if (tyfunc(t.Tty)) 1034 { 1035 int i; 1036 1037 i = 1; 1038 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext) 1039 { printf("\nP%d (%p): ",i++,p); 1040 fflush(stdout); 1041 1042 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext); 1043 param_debug(p); 1044 if (p.Pident) 1045 printf("'%s' ", p.Pident); 1046 type_print(p.Ptype); 1047 } 1048 } 1049 break; 1050 } 1051 printf("\n"); 1052 if (t.Tnext) type_print(t.Tnext); 1053 } 1054 1055 /******************************* 1056 * Pretty-print a param_t 1057 */ 1058 1059 @trusted 1060 void param_t_print(const scope param_t* p) 1061 { 1062 printf("Pident=%p,Ptype=%p,Pelem=%p,Psym=%p,Pnext=%p\n",p.Pident,p.Ptype,p.Pelem,p.Psym,p.Pnext); 1063 if (p.Pident) 1064 printf("\tPident = '%s'\n", p.Pident); 1065 if (p.Ptype) 1066 { printf("\tPtype =\n"); 1067 type_print(p.Ptype); 1068 } 1069 if (p.Pelem) 1070 { printf("\tPelem =\n"); 1071 elem_print(p.Pelem); 1072 } 1073 if (p.Pdeftype) 1074 { printf("\tPdeftype =\n"); 1075 type_print(p.Pdeftype); 1076 } 1077 if (p.Psym) 1078 { printf("\tPsym = '%s'\n", p.Psym.Sident.ptr); 1079 } 1080 if (p.Pptpl) 1081 { printf("\tPptpl = %p\n", p.Pptpl); 1082 } 1083 } 1084 1085 void param_t_print_list(scope param_t* p) 1086 { 1087 for (; p; p = p.Pnext) 1088 p.print(); 1089 } 1090 1091 1092 /**************************** 1093 * Allocate a param_t. 1094 */ 1095 1096 @trusted 1097 param_t *param_calloc() 1098 { 1099 static param_t pzero; 1100 param_t *p; 1101 1102 if (param_list) 1103 { 1104 p = param_list; 1105 param_list = p.Pnext; 1106 } 1107 else 1108 { 1109 p = cast(param_t *) mem_fmalloc(param_t.sizeof); 1110 } 1111 *p = pzero; 1112 1113 debug p.id = param_t.IDparam; 1114 1115 return p; 1116 } 1117 1118 /*************************** 1119 * Allocate a param_t of type t, and append it to parameter list. 1120 */ 1121 1122 param_t *param_append_type(param_t **pp,type *t) 1123 { param_t *p; 1124 1125 p = param_calloc(); 1126 while (*pp) 1127 { param_debug(*pp); 1128 pp = &((*pp).Pnext); /* find end of list */ 1129 } 1130 *pp = p; /* append p to list */ 1131 type_debug(t); 1132 p.Ptype = t; 1133 t.Tcount++; 1134 return p; 1135 } 1136 1137 /************************ 1138 * Version of param_free() suitable for list_free(). 1139 */ 1140 1141 @trusted 1142 void param_free_l(param_t *p) 1143 { 1144 param_free(&p); 1145 } 1146 1147 /*********************** 1148 * Free parameter list. 1149 * Output: 1150 * paramlst = null 1151 */ 1152 1153 @trusted 1154 void param_free(param_t **pparamlst) 1155 { param_t* p,pn; 1156 1157 //debug_assert(PARSER); 1158 for (p = *pparamlst; p; p = pn) 1159 { param_debug(p); 1160 pn = p.Pnext; 1161 type_free(p.Ptype); 1162 mem_free(p.Pident); 1163 el_free(p.Pelem); 1164 type_free(p.Pdeftype); 1165 if (p.Pptpl) 1166 param_free(&p.Pptpl); 1167 1168 debug p.id = 0; 1169 1170 p.Pnext = param_list; 1171 param_list = p; 1172 } 1173 *pparamlst = null; 1174 } 1175 1176 /*********************************** 1177 * Compute number of parameters 1178 */ 1179 1180 uint param_t_length(scope param_t* p) 1181 { 1182 uint nparams = 0; 1183 1184 for (; p; p = p.Pnext) 1185 nparams++; 1186 return nparams; 1187 } 1188 1189 /************************************* 1190 * Create template-argument-list blank from 1191 * template-parameter-list 1192 * Input: 1193 * ptali initial template-argument-list 1194 */ 1195 1196 @trusted 1197 param_t* param_t_createTal(scope param_t* p, param_t *ptali) 1198 { 1199 param_t *ptal = null; 1200 param_t **pp = &ptal; 1201 1202 for (; p; p = p.Pnext) 1203 { 1204 *pp = param_calloc(); 1205 if (p.Pident) 1206 { 1207 // Should find a way to just point rather than dup 1208 (*pp).Pident = cast(char *)mem_strdup(p.Pident); 1209 } 1210 if (ptali) 1211 { 1212 if (ptali.Ptype) 1213 { (*pp).Ptype = ptali.Ptype; 1214 (*pp).Ptype.Tcount++; 1215 } 1216 if (ptali.Pelem) 1217 { 1218 elem *e = el_copytree(ptali.Pelem); 1219 (*pp).Pelem = e; 1220 } 1221 (*pp).Psym = ptali.Psym; 1222 (*pp).Pflags = ptali.Pflags; 1223 assert(!ptali.Pptpl); 1224 ptali = ptali.Pnext; 1225 } 1226 pp = &(*pp).Pnext; 1227 } 1228 return ptal; 1229 } 1230 1231 /********************************** 1232 * Look for Pident matching id 1233 */ 1234 1235 @trusted 1236 param_t* param_t_search(return scope param_t* p, const(char)* id) 1237 { 1238 for (; p; p = p.Pnext) 1239 { 1240 if (p.Pident && strcmp(p.Pident, id) == 0) 1241 break; 1242 } 1243 return p; 1244 } 1245 1246 /********************************** 1247 * Look for Pident matching id 1248 */ 1249 1250 @trusted 1251 int param_t_searchn(param_t* p, char *id) 1252 { 1253 int n = 0; 1254 1255 for (; p; p = p.Pnext) 1256 { 1257 if (p.Pident && strcmp(p.Pident, id) == 0) 1258 return n; 1259 n++; 1260 } 1261 return -1; 1262 } 1263 1264 /************************************* 1265 * Search for member, create symbol as needed. 1266 * Used for symbol tables for VLA's such as: 1267 * void func(int n, int a[n]); 1268 */ 1269 1270 @trusted 1271 Symbol *param_search(const(char)* name, param_t **pp) 1272 { Symbol *s = null; 1273 param_t *p; 1274 1275 p = (*pp).search(cast(char *)name); 1276 if (p) 1277 { 1278 s = p.Psym; 1279 if (!s) 1280 { 1281 s = symbol_calloc(p.Pident[0 .. strlen(p.Pident)]); 1282 s.Sclass = SC.parameter; 1283 s.Stype = p.Ptype; 1284 s.Stype.Tcount++; 1285 p.Psym = s; 1286 } 1287 } 1288 return s; 1289 } 1290 1291 // Return TRUE if type lists match. 1292 private int paramlstmatch(param_t *p1,param_t *p2) 1293 { 1294 return p1 == p2 || 1295 p1 && p2 && typematch(p1.Ptype,p2.Ptype,0) && 1296 paramlstmatch(p1.Pnext,p2.Pnext) 1297 ; 1298 } 1299 1300 /************************************************* 1301 * A cheap version of exp2.typematch() and exp2.paramlstmatch(), 1302 * so that we can get cpp_mangle() to work for MARS. 1303 * It's less complex because it doesn't do templates and 1304 * can rely on strict typechecking. 1305 * Returns: 1306 * !=0 if types match. 1307 */ 1308 1309 @trusted 1310 int typematch(type *t1,type *t2,int relax) 1311 { tym_t t1ty, t2ty; 1312 tym_t tym; 1313 1314 tym = ~(mTYimport | mTYnaked); 1315 1316 return t1 == t2 || 1317 t1 && t2 && 1318 1319 ( 1320 /* ignore name mangling */ 1321 (t1ty = (t1.Tty & tym)) == (t2ty = (t2.Tty & tym)) 1322 ) 1323 && 1324 1325 (tybasic(t1ty) != TYarray || t1.Tdim == t2.Tdim || 1326 t1.Tflags & TFsizeunknown || t2.Tflags & TFsizeunknown) 1327 && 1328 1329 (tybasic(t1ty) != TYstruct 1330 && tybasic(t1ty) != TYenum 1331 && tybasic(t1ty) != TYmemptr 1332 || t1.Ttag == t2.Ttag) 1333 && 1334 1335 typematch(t1.Tnext,t2.Tnext, 0) 1336 && 1337 1338 (!tyfunc(t1ty) || 1339 ((t1.Tflags & TFfixed) == (t2.Tflags & TFfixed) && 1340 paramlstmatch(t1.Tparamtypes,t2.Tparamtypes) )) 1341 ; 1342 }