1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1984-1995 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: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/dcgcv.d, backend/dcgcv.d) 10 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/backend/dcgcv.d 11 */ 12 13 module dmd.backend.dcgcv; 14 15 version (SCPP) 16 version = COMPILE; 17 version (MARS) 18 version = COMPILE; 19 20 version (COMPILE) 21 { 22 23 import core.stdc.stdio; 24 import core.stdc.stdlib; 25 import core.stdc.string; 26 27 import dmd.backend.cc; 28 import dmd.backend.cdef; 29 import dmd.backend.cgcv; 30 import dmd.backend.code; 31 import dmd.backend.code_x86; 32 import dmd.backend.cv4; 33 import dmd.backend.dlist; 34 import dmd.backend.dvec; 35 import dmd.backend.el; 36 import dmd.backend.global; 37 import dmd.backend.mem; 38 import dmd.backend.obj; 39 import dmd.backend.outbuf; 40 import dmd.backend.symtab; 41 import dmd.backend.ty; 42 import dmd.backend.type; 43 44 import dmd.backend.barray; 45 46 version (SCPP) 47 { 48 import cpp; 49 import msgs2; 50 import parser; 51 } 52 version (MARS) 53 { 54 import dmd.backend.dvarstats; 55 } 56 57 extern (C++): 58 59 nothrow: 60 61 enum SYMDEB_TDB = false; 62 63 extern (C) void TOOFFSET(void* p, targ_size_t value) 64 { 65 switch (_tysize[TYnptr]) 66 { 67 case 2: *cast(ushort*)p = cast(ushort)value; break; 68 case 4: *cast(uint*) p = cast(uint) value; break; 69 case 8: *cast(ulong*) p = cast(ulong) value; break; 70 default: 71 assert(0); 72 } 73 } 74 75 extern __gshared char* ftdbname; 76 77 // Convert from SFL visibilities to CV4 protections 78 uint SFLtoATTR(uint sfl) { return 4 - ((sfl & SFLpmask) >> 5); } 79 80 __gshared 81 { 82 83 /* Dynamic array of debtyp_t's */ 84 private Barray!(debtyp_t*) debtyp; 85 86 private vec_t debtypvec; // vector of used entries 87 enum DEBTYPVECDIM = 16_001; //8009 //3001 // dimension of debtypvec (should be prime) 88 89 enum DEBTYPHASHDIM = 1009; 90 private uint[DEBTYPHASHDIM] debtyphash; 91 92 private Outbuffer *reset_symbuf; // Keep pointers to reset symbols 93 94 idx_t DEB_NULL() { return cgcv.deb_offset; } // index of null debug type record 95 96 /* This limitation is because of 4K page sizes 97 * in optlink/cv/cvhashes.asm 98 */ 99 enum CVIDMAX = (0xFF0-20); // the -20 is picked by trial and error 100 101 enum LOCATsegrel = 0xC000; 102 103 /* Unfortunately, the fixup stuff is different for EASY OMF and Microsoft */ 104 enum EASY_LCFDoffset = (LOCATsegrel | 0x1404); 105 enum EASY_LCFDpointer = (LOCATsegrel | 0x1800); 106 107 enum LCFD32offset = (LOCATsegrel | 0x2404); 108 enum LCFD32pointer = (LOCATsegrel | 0x2C00); 109 enum LCFD16pointer = (LOCATsegrel | 0x0C00); 110 111 version (MARS) 112 extern Cgcv cgcv; // already declared in cgcv.d 113 else 114 Cgcv cgcv; 115 116 } 117 118 version (MARS) 119 enum MARS = true; 120 else 121 enum MARS = false; 122 123 /****************************************** 124 * Return number of bytes consumed in OBJ file by a name. 125 */ 126 127 int cv_stringbytes(const(char)* name) 128 { 129 int len = cast(int)strlen(name); 130 if (config.fulltypes == CV8) 131 return len + 1; 132 if (len > CVIDMAX) 133 len = CVIDMAX; 134 return len + ((len > 255) ? 4 : 1); 135 } 136 137 /****************************************** 138 * Stuff a namestring into p. 139 * Returns: 140 * number of bytes consumed 141 */ 142 143 int cv_namestring(ubyte *p, const(char)* name, int length = -1) 144 { 145 size_t len = (length >= 0) ? length : strlen(name); 146 if (config.fulltypes == CV8) 147 { 148 size_t numBytesWritten = len + ((length < 0) ? 1 : 0); 149 memcpy(p, name, numBytesWritten); 150 if(config.flags2 & CFG2gms) 151 { 152 for(int i = 0; i < len; i++) 153 { 154 if(p[i] == '.') 155 p[i] = '@'; 156 } 157 } 158 return cast(int)numBytesWritten; 159 } 160 if (len > 255) 161 { p[0] = 0xFF; 162 p[1] = 0; 163 if (len > CVIDMAX) 164 len = CVIDMAX; 165 TOWORD(p + 2,cast(uint)len); 166 memcpy(p + 4,name,len); 167 len += 4; 168 } 169 else 170 { p[0] = cast(ubyte)len; 171 memcpy(p + 1,name,len); 172 len++; 173 } 174 return cast(int)len; 175 } 176 177 /*********************************** 178 * Compute debug register number for symbol s. 179 * Returns: 180 * 0..7 byte registers 181 * 8..15 word registers 182 * 16..23 dword registers 183 */ 184 185 private int cv_regnum(Symbol *s) 186 { 187 uint reg = s.Sreglsw; 188 if (s.Sclass == SCpseudo) 189 { 190 version (SCPP) 191 reg = pseudoreg[reg]; 192 } 193 else 194 { 195 assert(reg < 8); 196 assert(s.Sfl == FLreg); 197 switch (type_size(s.Stype)) 198 { 199 case LONGSIZE: 200 case 3: reg += 8; 201 goto case; 202 203 case SHORTSIZE: reg += 8; 204 goto case; 205 206 case CHARSIZE: break; 207 208 case LLONGSIZE: 209 reg += (s.Sregmsw << 8) + (16 << 8) + 16; 210 if (config.fulltypes == CV4) 211 reg += (1 << 8); 212 break; 213 214 default: 215 static if (0) 216 { 217 symbol_print(s); 218 type_print(s.Stype); 219 printf("size = %d\n",type_size(s.Stype)); 220 } 221 assert(0); 222 } 223 } 224 if (config.fulltypes == CV4) 225 reg++; 226 return reg; 227 } 228 229 /*********************************** 230 * Allocate a debtyp_t. 231 */ 232 233 debtyp_t * debtyp_alloc(uint length) 234 { 235 debtyp_t *d; 236 uint pad = 0; 237 238 //printf("len = %u, x%x\n", length, length); 239 if (config.fulltypes == CV8) 240 { // length+2 must lie on 4 byte boundary 241 pad = ((length + 2 + 3) & ~3) - (length + 2); 242 length += pad; 243 } 244 245 length < 0x10000 || assert(0); 246 const len = debtyp_t.sizeof - (d.data).sizeof + length; 247 debug 248 { 249 d = cast(debtyp_t *) mem_malloc(len /*+ 1*/); 250 memset(d, 0xAA, len); 251 // (cast(char*)d)[len] = 0x2E; 252 } 253 else 254 { 255 d = cast(debtyp_t *) malloc(debtyp_t.sizeof - (d.data).sizeof + length); 256 } 257 d.length = cast(ushort)length; 258 if (pad) 259 { 260 __gshared const ubyte[3] padx = [0xF3, 0xF2, 0xF1]; 261 memcpy(d.data.ptr + length - pad, padx.ptr + 3 - pad, pad); 262 } 263 //printf("debtyp_alloc(%d) = %p\n", length, d); 264 return d; 265 } 266 267 /*********************************** 268 * Free a debtyp_t. 269 */ 270 271 private void debtyp_free(debtyp_t *d) 272 { 273 //printf("debtyp_free(length = %d, %p)\n", d.length, d); 274 //fflush(stdout); 275 debug 276 { 277 assert(d.length < 0x10000); 278 uint len = debtyp_t.sizeof - (d.data).sizeof + d.length; 279 // assert((cast(char*)d)[len] == 0x2E); 280 memset(d, 0x55, len); 281 mem_free(d); 282 } 283 else 284 { 285 free(d); 286 } 287 } 288 289 static if (0) 290 { 291 void debtyp_check(debtyp_t *d,int linnum) 292 { int i; 293 __gshared char c; 294 295 //printf("linnum = %d\n",linnum); 296 //printf(" length = %d\n",d.length); 297 for (i = 0; i < d.length; i++) 298 c = d.data.ptr[i]; 299 } 300 301 void debtyp_check(debtyp_t* d) { debtyp_check(d,__LINE__); } 302 } 303 else 304 { 305 void debtyp_check(debtyp_t* d) { } 306 } 307 308 /*********************************** 309 * Search for debtyp_t in debtyp[]. If it is there, return the index 310 * of it, and free d. Otherwise, add it. 311 * Returns: 312 * index in debtyp[] 313 */ 314 315 idx_t cv_debtyp(debtyp_t *d) 316 { 317 ushort length; 318 uint hashi; 319 320 assert(d); 321 length = d.length; 322 //printf("length = %3d\n",length); 323 static if (SYMDEB_TDB) 324 { 325 if (config.fulltypes == CVTDB) 326 { 327 idx_t result; 328 329 static if (1) 330 { 331 assert(length); 332 debtyp_check(d); 333 result = tdb_typidx(&d.length); 334 } 335 else 336 { 337 ubyte *buf; 338 339 // Allocate buffer 340 buf = malloc(6 + length); 341 if (!buf) 342 err_nomem(); // out of memory 343 344 // Fill the buffer 345 TOLONG(buf,cgcv.signature); 346 memcpy(buf + 4,cast(char *)d + uint.sizeof,2 + length); 347 348 static if (0) 349 { 350 {int i; 351 for (i=0;i<length;i++) 352 printf("%02x ",buf[6+i]); 353 printf("\n"); 354 } 355 } 356 result = tdb_typidx(buf,6 + length); 357 } 358 //printf("result = x%x\n",result); 359 debtyp_free(d); 360 return result; 361 } 362 } 363 if (length) 364 { uint hash; 365 366 hash = length; 367 if (length >= uint.sizeof) 368 { 369 // Hash consists of the sum of the first 4 bytes with the last 4 bytes 370 union U { ubyte* cp; uint* up; } 371 U un = void; 372 un.cp = d.data.ptr; 373 hash += *un.up; 374 un.cp += length - uint.sizeof; 375 hash += *un.up; 376 } 377 hashi = hash % DEBTYPHASHDIM; 378 hash %= DEBTYPVECDIM; 379 //printf(" hashi = %d", hashi); 380 381 if (vec_testbit(hash,debtypvec)) 382 { 383 //printf(" test"); 384 // Threaded list is much faster 385 for (uint u = debtyphash[hashi]; u; u = debtyp[u].prev) 386 //for (uint u = debtyp.length; u--; ) 387 { 388 if (length == debtyp[u].length && 389 memcmp(d.data.ptr,debtyp[u].data.ptr,length) == 0) 390 { debtyp_free(d); 391 //printf(" match %d\n",u); 392 return u + cgcv.deb_offset; 393 } 394 } 395 } 396 else 397 vec_setbit(hash,debtypvec); 398 } 399 else 400 hashi = 1; 401 //printf(" add %d\n",debtyp.length); 402 d.prev = debtyphash[hashi]; 403 debtyphash[hashi] = cast(uint)debtyp.length; 404 405 /* It's not already in the array, so add it */ 406 debtyp.push(d); 407 version (SCPP) 408 { 409 if (debtyp.length >= 0xE000) 410 err_fatal(EM_2manytypes,0xE000); // too many types 411 } 412 413 return cast(uint)debtyp.length - 1 + cgcv.deb_offset; 414 } 415 416 idx_t cv_numdebtypes() 417 { 418 return cast(idx_t)debtyp.length; 419 } 420 421 /**************************** 422 * Store a null record at DEB_NULL. 423 */ 424 425 void cv_init() 426 { debtyp_t *d; 427 428 //printf("cv_init()\n"); 429 430 // Initialize statics 431 debtyp.setLength(0); 432 if (!ftdbname) 433 ftdbname = cast(char *)"symc.tdb".ptr; 434 435 memset(&cgcv,0,cgcv.sizeof); 436 cgcv.sz_idx = 2; 437 cgcv.LCFDoffset = LCFD32offset; 438 cgcv.LCFDpointer = LCFD16pointer; 439 440 debtypvec = vec_calloc(DEBTYPVECDIM); 441 memset(debtyphash.ptr,0,debtyphash.sizeof); 442 443 if (reset_symbuf) 444 { 445 Symbol **p = cast(Symbol **)reset_symbuf.buf; 446 const size_t n = reset_symbuf.length() / (Symbol *).sizeof; 447 for (size_t i = 0; i < n; ++i) 448 symbol_reset(p[i]); 449 reset_symbuf.reset(); 450 } 451 else 452 { 453 reset_symbuf = cast(Outbuffer*) calloc(1, Outbuffer.sizeof); 454 assert(reset_symbuf); 455 reset_symbuf.reserve(10 * (Symbol*).sizeof); 456 } 457 458 /* Reset for different OBJ file formats */ 459 if (I32 || I64) 460 { 461 // Adjust values in old CV tables for 32 bit ints 462 dttab[TYenum] = dttab[TYlong]; 463 dttab[TYint] = dttab[TYlong]; 464 dttab[TYuint] = dttab[TYulong]; 465 466 // Adjust Codeview 4 values for 32 bit ints and 32 bit pointer offsets 467 dttab4[TYenum] = 0x74; 468 dttab4[TYint] = 0x74; 469 dttab4[TYuint] = 0x75; 470 if (I64) 471 { 472 dttab4[TYptr] = 0x600; 473 dttab4[TYnptr] = 0x600; 474 dttab4[TYsptr] = 0x600; 475 dttab4[TYimmutPtr] = 0x600; 476 dttab4[TYsharePtr] = 0x600; 477 dttab4[TYrestrictPtr] = 0x600; 478 dttab4[TYfgPtr] = 0x600; 479 } 480 else 481 { 482 dttab4[TYptr] = 0x400; 483 dttab4[TYsptr] = 0x400; 484 dttab4[TYnptr] = 0x400; 485 dttab4[TYimmutPtr] = 0x400; 486 dttab4[TYsharePtr] = 0x400; 487 dttab4[TYrestrictPtr] = 0x400; 488 dttab4[TYfgPtr] = 0x400; 489 } 490 dttab4[TYcptr] = 0x400; 491 dttab4[TYfptr] = 0x500; 492 493 if (config.flags & CFGeasyomf) 494 { cgcv.LCFDoffset = EASY_LCFDoffset; 495 cgcv.LCFDpointer = EASY_LCFDpointer; 496 assert(config.fulltypes == CVOLD); 497 } 498 else 499 cgcv.LCFDpointer = LCFD32pointer; 500 501 if (config.exe & EX_flat) 502 cgcv.FD_code = 0x10; 503 } 504 505 if (config.fulltypes >= CV4) 506 { int flags; 507 __gshared ushort[5] memmodel = [0,0x100,0x20,0x120,0x120]; 508 char[1 + (VERSION).sizeof] version_; 509 ubyte[8 + (version_).sizeof] debsym; 510 511 // Put out signature indicating CV4 format 512 switch (config.fulltypes) 513 { 514 case CV4: 515 cgcv.signature = 1; 516 break; 517 518 case CV8: 519 cgcv.signature = 4; 520 break; 521 522 default: 523 { const(char)* x = "1MYS"; 524 cgcv.signature = *cast(int *) x; 525 break; 526 } 527 } 528 529 cgcv.deb_offset = 0x1000; 530 531 if (config.fulltypes == CV8) 532 { cgcv.sz_idx = 4; 533 return; // figure out rest later 534 } 535 536 if (config.fulltypes >= CVSYM) 537 { cgcv.sz_idx = 4; 538 if (!(config.flags2 & CFG2phgen)) 539 cgcv.deb_offset = 0x80000000; 540 } 541 542 objmod.write_bytes(SegData[DEBSYM],4,&cgcv.signature); 543 544 // Allocate an LF_ARGLIST with no arguments 545 if (config.fulltypes == CV4) 546 { d = debtyp_alloc(4); 547 TOWORD(d.data.ptr,LF_ARGLIST); 548 TOWORD(d.data.ptr + 2,0); 549 } 550 else 551 { d = debtyp_alloc(6); 552 TOWORD(d.data.ptr,LF_ARGLIST); 553 TOLONG(d.data.ptr + 2,0); 554 } 555 556 // Put out S_COMPILE record 557 TOWORD(debsym.ptr + 2,S_COMPILE); 558 switch (config.target_cpu) 559 { 560 case TARGET_8086: debsym[4] = 0; break; 561 case TARGET_80286: debsym[4] = 2; break; 562 case TARGET_80386: debsym[4] = 3; break; 563 case TARGET_80486: debsym[4] = 4; break; 564 565 case TARGET_Pentium: 566 case TARGET_PentiumMMX: 567 debsym[4] = 5; break; 568 569 case TARGET_PentiumPro: 570 case TARGET_PentiumII: 571 debsym[4] = 6; break; 572 default: assert(0); 573 } 574 debsym[5] = (CPP != 0); // 0==C, 1==C++ 575 flags = (config.inline8087) ? (0<<3) : (1<<3); 576 if (I32) 577 flags |= 0x80; // 32 bit addresses 578 flags |= memmodel[config.memmodel]; 579 TOWORD(debsym.ptr + 6,flags); 580 version_[0] = 'Z'; 581 strcpy(version_.ptr + 1,VERSION); 582 cv_namestring(debsym.ptr + 8,version_.ptr); 583 TOWORD(debsym.ptr,6 + (version_).sizeof); 584 objmod.write_bytes(SegData[DEBSYM],8 + (version_).sizeof,debsym.ptr); 585 586 static if (SYMDEB_TDB) 587 { 588 // Put out S_TDBNAME record 589 if (config.fulltypes == CVTDB) 590 { 591 ubyte[50] buf = void; 592 593 pstate.STtdbtimestamp = tdb_gettimestamp(); 594 size_t len = cv_stringbytes(ftdbname); 595 ubyte *ds = (8 + len <= buf.sizeof) ? buf : cast(ubyte *) malloc(8 + len); 596 assert(ds); 597 TOWORD(ds,6 + len); 598 TOWORD(ds + 2,S_TDBNAME); 599 TOLONG(ds + 4,pstate.STtdbtimestamp); 600 cv_namestring(ds + 8,ftdbname); 601 objmod.write_bytes(SegData[DEBSYM],8 + len,ds); 602 if (ds != buf) 603 free(ds); 604 } 605 } 606 } 607 else 608 { 609 assert(0); 610 } 611 if (config.fulltypes == CVTDB) 612 cgcv.deb_offset = cv_debtyp(d); 613 else 614 cv_debtyp(d); 615 } 616 617 /////////////////////////// CodeView 4 /////////////////////////////// 618 619 /*********************************** 620 * Return number of bytes required to store a numeric leaf. 621 */ 622 623 uint cv4_numericbytes(uint value) 624 { uint u; 625 626 if (value < 0x8000) 627 u = 2; 628 else if (value < 0x10000) 629 u = 4; 630 else 631 u = 6; 632 return u; 633 } 634 635 /******************************** 636 * Store numeric leaf. 637 * Must use exact same number of bytes as cv4_numericbytes(). 638 */ 639 640 void cv4_storenumeric(ubyte *p, uint value) 641 { 642 if (value < 0x8000) 643 TOWORD(p,value); 644 else if (value < 0x10000) 645 { TOWORD(p,LF_USHORT); 646 p += 2; 647 TOWORD(p,value); 648 } 649 else 650 { TOWORD(p,LF_ULONG); 651 *cast(targ_ulong *)(p + 2) = cast(uint) value; 652 } 653 } 654 655 /*********************************** 656 * Return number of bytes required to store a signed numeric leaf. 657 * Params: 658 * value = value to store 659 * Returns: 660 * number of bytes required for storing value 661 */ 662 uint cv4_signednumericbytes(int value) 663 { 664 uint u; 665 if (value >= 0 && value < 0x8000) 666 u = 2; 667 else if (value == cast(short)value) 668 u = 4; 669 else 670 u = 6; 671 return u; 672 } 673 674 /******************************** 675 * Store signed numeric leaf. 676 * Must use exact same number of bytes as cv4_signednumericbytes(). 677 * Params: 678 * p = address where to store value 679 * value = value to store 680 */ 681 void cv4_storesignednumeric(ubyte *p, int value) 682 { 683 if (value >= 0 && value < 0x8000) 684 TOWORD(p, value); 685 else if (value == cast(short)value) 686 { 687 TOWORD(p, LF_SHORT); 688 TOWORD(p + 2, value); 689 } 690 else 691 { 692 TOWORD(p,LF_LONG); 693 TOLONG(p + 2, value); 694 } 695 } 696 697 /********************************* 698 * Generate a type index for a parameter list. 699 */ 700 701 idx_t cv4_arglist(type *t,uint *pnparam) 702 { uint u; 703 uint nparam; 704 idx_t paramidx; 705 debtyp_t *d; 706 param_t *p; 707 708 // Compute nparam, number of parameters 709 nparam = 0; 710 for (p = t.Tparamtypes; p; p = p.Pnext) 711 nparam++; 712 *pnparam = nparam; 713 714 // Construct an LF_ARGLIST of those parameters 715 if (nparam == 0) 716 { 717 if (config.fulltypes == CV8) 718 { 719 d = debtyp_alloc(2 + 4 + 4); 720 TOWORD(d.data.ptr,LF_ARGLIST_V2); 721 TOLONG(d.data.ptr + 2,1); 722 TOLONG(d.data.ptr + 6,0); 723 paramidx = cv_debtyp(d); 724 } 725 else 726 paramidx = DEB_NULL; 727 } 728 else 729 { 730 switch (config.fulltypes) 731 { 732 case CV8: 733 d = debtyp_alloc(2 + 4 + nparam * 4); 734 TOWORD(d.data.ptr,LF_ARGLIST_V2); 735 TOLONG(d.data.ptr + 2,nparam); 736 737 p = t.Tparamtypes; 738 for (u = 0; u < nparam; u++) 739 { TOLONG(d.data.ptr + 6 + u * 4,cv4_typidx(p.Ptype)); 740 p = p.Pnext; 741 } 742 break; 743 744 case CV4: 745 d = debtyp_alloc(2 + 2 + nparam * 2); 746 TOWORD(d.data.ptr,LF_ARGLIST); 747 TOWORD(d.data.ptr + 2,nparam); 748 749 p = t.Tparamtypes; 750 for (u = 0; u < nparam; u++) 751 { TOWORD(d.data.ptr + 4 + u * 2,cv4_typidx(p.Ptype)); 752 p = p.Pnext; 753 } 754 break; 755 756 default: 757 d = debtyp_alloc(2 + 4 + nparam * 4); 758 TOWORD(d.data.ptr,LF_ARGLIST); 759 TOLONG(d.data.ptr + 2,nparam); 760 761 p = t.Tparamtypes; 762 for (u = 0; u < nparam; u++) 763 { TOLONG(d.data.ptr + 6 + u * 4,cv4_typidx(p.Ptype)); 764 p = p.Pnext; 765 } 766 break; 767 } 768 paramidx = cv_debtyp(d); 769 } 770 return paramidx; 771 } 772 773 /***************************** 774 * Build LF_METHODLIST for overloaded member function. 775 * Output: 776 * *pcount # of entries in method list 777 * Returns: 778 * type index of method list 779 * 0 don't do this one 780 */ 781 782 version (SCPP) 783 { 784 785 private int cv4_methodlist(Symbol *sf,int *pcount) 786 { int count; 787 int mlen; 788 Symbol *s; 789 debtyp_t *d; 790 ubyte *p; 791 ushort attribute; 792 793 symbol_debug(sf); 794 795 // First, compute how big the method list is 796 count = 0; 797 mlen = 2; 798 for (s = sf; s; s = s.Sfunc.Foversym) 799 { 800 if (s.Sclass == SCtypedef || s.Sclass == SCfunctempl) 801 continue; 802 if (s.Sfunc.Fflags & Fnodebug) 803 continue; 804 if (s.Sfunc.Fflags & Fintro) 805 mlen += 4; 806 mlen += cgcv.sz_idx * 2; 807 count++; 808 } 809 810 if (!count) 811 return 0; 812 813 // Allocate and fill it in 814 d = debtyp_alloc(mlen); 815 p = d.data.ptr; 816 TOWORD(p,LF_METHODLIST); 817 p += 2; 818 for (s = sf; s; s = s.Sfunc.Foversym) 819 { 820 if (s.Sclass == SCtypedef || s.Sclass == SCfunctempl) 821 continue; 822 if (s.Sfunc.Fflags & Fnodebug) 823 continue; 824 attribute = cast(ushort)SFLtoATTR(s.Sflags); 825 // Make sure no overlapping bits 826 assert((Fvirtual | Fpure | Fintro | Fstatic) == (Fvirtual ^ Fpure ^ Fintro ^ Fstatic)); 827 switch ((s.Sfunc.Fflags & (Fvirtual | Fstatic)) | 828 (s.Sfunc.Fflags & (Fpure | Fintro))) 829 { 830 // BUG: should we have 0x0C, friend functions? 831 case Fstatic: attribute |= 0x08; break; 832 case Fvirtual: attribute |= 0x04; break; 833 case Fvirtual | Fintro: attribute |= 0x10; break; 834 case Fvirtual | Fpure: attribute |= 0x14; break; 835 case Fvirtual | Fintro | Fpure: attribute |= 0x18; break; 836 837 case 0: 838 break; 839 840 default: 841 symbol_print(s); 842 assert(0); 843 } 844 TOIDX(p,attribute); 845 p += cgcv.sz_idx; 846 TOIDX(p,cv4_symtypidx(s)); 847 p += cgcv.sz_idx; 848 if (s.Sfunc.Fflags & Fintro) 849 { TOLONG(p,cpp_vtbloffset(cast(Classsym *)s.Sscope,s)); 850 p += 4; 851 } 852 } 853 assert(p - d.data.ptr == mlen); 854 855 *pcount = count; 856 return cv_debtyp(d); 857 } 858 859 } 860 861 /********************************** 862 * Pretty-print indentifier for CV4 types. 863 */ 864 865 version (SCPP) 866 { 867 868 private const(char)* cv4_prettyident(Symbol *s) 869 { Symbol *stmp; 870 871 stmp = s.Sscope; 872 s.Sscope = null; // trick cpp_prettyident into leaving off :: 873 const p = cpp_prettyident(s); 874 s.Sscope = cast(Classsym *)stmp; 875 return p; 876 } 877 878 } 879 880 /**************************** 881 * Return type index of struct. 882 * Input: 883 * s struct tag symbol 884 * flags 885 * 0 generate a reference to s 886 * 1 just saw the definition of s 887 * 2 saw key function for class s 888 * 3 no longer have a key function for class s 889 */ 890 891 idx_t cv4_struct(Classsym *s,int flags) 892 { targ_size_t size; 893 debtyp_t* d,dt; 894 uint len; 895 uint nfields,fnamelen; 896 idx_t typidx; 897 type *t; 898 struct_t *st; 899 const(char)* id; 900 version (SCPP) 901 { 902 baseclass_t *b; 903 } 904 uint numidx; 905 uint leaf; 906 uint property; 907 uint attribute; 908 ubyte *p; 909 int refonly; 910 int i; 911 int count; // COUNT field in LF_CLASS 912 913 symbol_debug(s); 914 assert(config.fulltypes >= CV4); 915 st = s.Sstruct; 916 if (st.Sflags & STRanonymous) // if anonymous class/union 917 return 0; 918 919 //printf("cv4_struct(%s,%d)\n",s.Sident.ptr,flags); 920 t = s.Stype; 921 //printf("t = %p, Tflags = x%x\n", t, t.Tflags); 922 type_debug(t); 923 924 // Determine if we should do a reference or a definition 925 refonly = 1; // assume reference only 926 if (MARS || t.Tflags & TFsizeunknown || st.Sflags & STRoutdef) 927 { 928 //printf("ref only\n"); 929 } 930 else 931 { 932 // We have a definition that we have not put out yet 933 switch (flags) 934 { 935 case 0: // reference to s 936 version (SCPP) 937 { 938 if (!CPP || 939 config.flags2 & (CFG2fulltypes | CFG2hdrdebug) || 940 !(st.Sflags & STRvtblext)) 941 refonly = 0; 942 } 943 else 944 { 945 refonly = 0; 946 } 947 break; 948 949 case 1: // saw def of s 950 if (!s.Stypidx) // if not forward referenced 951 return 0; 952 version (SCPP) 953 { 954 if (!CPP || 955 config.flags2 & CFG2fulltypes || 956 !(st.Sflags & STRvtblext)) 957 refonly = 0; 958 } 959 break; 960 961 version (SCPP) 962 { 963 case 2: // saw key func for s 964 if (config.flags2 & CFG2fulltypes) 965 return 0; 966 refonly = 0; 967 break; 968 969 case 3: // no longer have key func for s 970 if (!s.Stypidx || config.flags2 & CFG2fulltypes) 971 return 0; 972 refonly = 0; 973 break; 974 } 975 default: 976 assert(0); 977 } 978 } 979 980 if (MARS || refonly) 981 { 982 if (s.Stypidx) // if reference already generated 983 { //assert(s.Stypidx - cgcv.deb_offset < debtyp.length); 984 return s.Stypidx; // use already existing reference 985 } 986 size = 0; 987 property = 0x80; // class is forward referenced 988 } 989 else 990 { size = type_size(t); 991 st.Sflags |= STRoutdef; 992 property = 0; 993 } 994 995 version (SCPP) 996 { 997 if (CPP) 998 { 999 if (s.Sscope) // if class is nested 1000 property |= 8; 1001 if (st.Sctor || st.Sdtor) 1002 property |= 2; // class has ctors and/or dtors 1003 if (st.Sopoverload) 1004 property |= 4; // class has overloaded operators 1005 if (st.Scastoverload) 1006 property |= 0x40; // class has casting methods 1007 if (st.Sopeq && !(st.Sopeq.Sfunc.Fflags & Fnodebug)) 1008 property |= 0x20; // class has overloaded assignment 1009 } 1010 } 1011 id = prettyident(s); 1012 if (config.fulltypes == CV4) 1013 { numidx = (st.Sflags & STRunion) ? 8 : 12; 1014 len = numidx + cv4_numericbytes(cast(uint)size); 1015 d = debtyp_alloc(len + cv_stringbytes(id)); 1016 cv4_storenumeric(d.data.ptr + numidx,cast(uint)size); 1017 } 1018 else 1019 { numidx = (st.Sflags & STRunion) ? 10 : 18; 1020 len = numidx + 4; 1021 d = debtyp_alloc(len + cv_stringbytes(id)); 1022 TOLONG(d.data.ptr + numidx,cast(uint)size); 1023 } 1024 len += cv_namestring(d.data.ptr + len,id); 1025 switch (s.Sclass) 1026 { 1027 case SCstruct: 1028 leaf = LF_STRUCTURE; 1029 if (st.Sflags & STRunion) 1030 { leaf = LF_UNION; 1031 break; 1032 } 1033 if (st.Sflags & STRclass) 1034 leaf = LF_CLASS; 1035 goto L1; 1036 L1: 1037 if (config.fulltypes == CV4) 1038 TOWORD(d.data.ptr + 8,0); // dList 1039 else 1040 TOLONG(d.data.ptr + 10,0); // dList 1041 if (CPP) 1042 { 1043 version (SCPP) 1044 { 1045 debtyp_t *vshape; 1046 ubyte descriptor; 1047 1048 const n = list_nitems(st.Svirtual); 1049 if (n == 0) // if no virtual functions 1050 { 1051 if (config.fulltypes == CV4) 1052 TOWORD(d.data.ptr + 10,0); // vshape is 0 1053 else 1054 TOLONG(d.data.ptr + 14,0); // vshape is 0 1055 } 1056 else 1057 { 1058 vshape = debtyp_alloc(4 + (n + 1) / 2); 1059 TOWORD(vshape.data.ptr,LF_VTSHAPE); 1060 TOWORD(vshape.data.ptr + 2,1); 1061 1062 uint n2 = 0; 1063 descriptor = 0; 1064 foreach (vl; ListRange(st.Svirtual)) 1065 { mptr_t *m; 1066 tym_t ty; 1067 1068 m = list_mptr(vl); 1069 symbol_debug(m.MPf); 1070 ty = tybasic(m.MPf.ty()); 1071 assert(tyfunc(ty)); 1072 if (_tysize[TYint] == 4) 1073 descriptor |= 5; 1074 if (tyfarfunc(ty)) 1075 descriptor++; 1076 vshape.data.ptr[4 + n2 / 2] = descriptor; 1077 descriptor <<= 4; 1078 n2++; 1079 } 1080 if (config.fulltypes == CV4) 1081 TOWORD(d.data.ptr + 10,cv_debtyp(vshape)); // vshape 1082 else 1083 TOLONG(d.data.ptr + 14,cv_debtyp(vshape)); // vshape 1084 } 1085 } 1086 } 1087 else 1088 { 1089 if (config.fulltypes == CV4) 1090 TOWORD(d.data.ptr + 10,0); // vshape 1091 else 1092 TOLONG(d.data.ptr + 14,0); // vshape 1093 } 1094 break; 1095 1096 default: 1097 symbol_print(s); 1098 assert(0); 1099 } 1100 TOWORD(d.data.ptr,leaf); 1101 1102 // Assign a number to prevent infinite recursion if a struct member 1103 // references the same struct. 1104 if (config.fulltypes == CVTDB) 1105 { 1106 static if (SYMDEB_TDB) 1107 { 1108 TOWORD(d.data.ptr + 2,0); // number of fields 1109 TOLONG(d.data.ptr + 6,0); // field list is 0 1110 TOWORD(d.data.ptr + 4,property | 0x80); // set fwd ref bit 1111 static if (0) 1112 { 1113 printf("fwd struct ref\n"); 1114 {int i; 1115 printf("len = %d, length = %d\n",len,d.length); 1116 for (i=0;i<d.length;i++) 1117 printf("%02x ",d.data.ptr[i]); 1118 printf("\n"); 1119 } 1120 } 1121 debtyp_check(d); 1122 s.Stypidx = tdb_typidx(&d.length); // forward reference it 1123 } 1124 } 1125 else 1126 { 1127 d.length = 0; // so cv_debtyp() will allocate new 1128 s.Stypidx = cv_debtyp(d); 1129 d.length = cast(ushort)len; // restore length 1130 } 1131 reset_symbuf.write((&s)[0 .. 1]); 1132 1133 if (refonly) // if reference only 1134 { 1135 //printf("refonly\n"); 1136 TOWORD(d.data.ptr + 2,0); // count: number of fields is 0 1137 if (config.fulltypes == CV4) 1138 { TOWORD(d.data.ptr + 4,0); // field list is 0 1139 TOWORD(d.data.ptr + 6,property); 1140 } 1141 else 1142 { TOLONG(d.data.ptr + 6,0); // field list is 0 1143 TOWORD(d.data.ptr + 4,property); 1144 } 1145 return s.Stypidx; 1146 } 1147 1148 version (MARS) 1149 util_progress(); 1150 else 1151 file_progress(); 1152 1153 // Compute the number of fields, and the length of the fieldlist record 1154 nfields = 0; 1155 fnamelen = 2; 1156 version (SCPP) 1157 { 1158 if (CPP) 1159 { 1160 // Base classes come first 1161 for (b = st.Sbase; b; b = b.BCnext) 1162 { 1163 if (b.BCflags & BCFvirtual) // skip virtual base classes 1164 continue; 1165 nfields++; 1166 fnamelen += ((config.fulltypes == CV4) ? 6 : 8) + 1167 cv4_numericbytes(b.BCoffset); 1168 } 1169 1170 // Now virtual base classes (direct and indirect) 1171 for (b = st.Svirtbase; b; b = b.BCnext) 1172 { 1173 nfields++; 1174 fnamelen += ((config.fulltypes == CV4) ? 8 : 12) + 1175 cv4_numericbytes(st.Svbptr_off) + 1176 cv4_numericbytes(b.BCvbtbloff / _tysize[TYint]); 1177 } 1178 1179 // Now friend classes 1180 i = list_nitems(st.Sfriendclass); 1181 nfields += i; 1182 fnamelen += i * ((config.fulltypes == CV4) ? 4 : 8); 1183 1184 // Now friend functions 1185 foreach (sl; ListRange(st.Sfriendfuncs)) 1186 { Symbol *sf = list_symbol(sl); 1187 1188 symbol_debug(sf); 1189 if (sf.Sclass == SCfunctempl) 1190 continue; 1191 nfields++; 1192 fnamelen += ((config.fulltypes == CV4) ? 4 : 6) + 1193 cv_stringbytes(cpp_unmangleident(sf.Sident.ptr)); 1194 } 1195 } 1196 } 1197 count = nfields; 1198 foreach (sl; ListRange(st.Sfldlst)) 1199 { Symbol *sf = list_symbol(sl); 1200 targ_size_t offset; 1201 1202 symbol_debug(sf); 1203 const(char)* sfid = sf.Sident.ptr; 1204 switch (sf.Sclass) 1205 { 1206 case SCmember: 1207 case SCfield: 1208 if (CPP && sf == s.Sstruct.Svptr) 1209 fnamelen += ((config.fulltypes == CV4) ? 4 : 8); 1210 else 1211 { offset = sf.Smemoff; 1212 fnamelen += ((config.fulltypes == CV4) ? 6 : 8) + 1213 cv4_numericbytes(cast(uint)offset) + cv_stringbytes(sfid); 1214 } 1215 break; 1216 1217 version (SCPP) 1218 { 1219 case SCstruct: 1220 if (sf.Sstruct.Sflags & STRanonymous) 1221 continue; 1222 if (sf.Sstruct.Sflags & STRnotagname) 1223 sfid = cpp_name_none.ptr; 1224 property |= 0x10; // class contains nested classes 1225 goto Lnest2; 1226 1227 case SCenum: 1228 if (sf.Senum.SEflags & SENnotagname) 1229 sfid = cpp_name_none.ptr; 1230 goto Lnest2; 1231 1232 case SCtypedef: 1233 Lnest2: 1234 fnamelen += ((config.fulltypes == CV4) ? 4 : 8) + 1235 cv_stringbytes(sfid); 1236 break; 1237 1238 case SCextern: 1239 case SCcomdef: 1240 case SCglobal: 1241 case SCstatic: 1242 case SCinline: 1243 case SCsinline: 1244 case SCeinline: 1245 case SCcomdat: 1246 if (tyfunc(sf.ty())) 1247 { Symbol *so; 1248 int nfuncs; 1249 1250 nfuncs = 0; 1251 for (so = sf; so; so = so.Sfunc.Foversym) 1252 { 1253 if (so.Sclass == SCtypedef || 1254 so.Sclass == SCfunctempl || 1255 so.Sfunc.Fflags & Fnodebug) // if compiler generated 1256 continue; // skip it 1257 nfuncs++; 1258 } 1259 if (nfuncs == 0) 1260 continue; 1261 1262 if (nfuncs > 1) 1263 count += nfuncs - 1; 1264 1265 sfid = cv4_prettyident(sf); 1266 } 1267 fnamelen += ((config.fulltypes == CV4) ? 6 : 8) + 1268 cv_stringbytes(sfid); 1269 break; 1270 } 1271 1272 default: 1273 continue; 1274 } 1275 nfields++; 1276 count++; 1277 } 1278 1279 TOWORD(d.data.ptr + 2,count); 1280 if (config.fulltypes == CV4) 1281 TOWORD(d.data.ptr + 6,property); 1282 else 1283 TOWORD(d.data.ptr + 4,property); 1284 1285 // Generate fieldlist type record 1286 dt = debtyp_alloc(fnamelen); 1287 p = dt.data.ptr; 1288 TOWORD(p,LF_FIELDLIST); 1289 1290 // And fill it in 1291 p += 2; 1292 version (SCPP) 1293 { 1294 if (CPP) 1295 { 1296 // Put out real base classes 1297 for (b = st.Sbase; b; b = b.BCnext) 1298 { targ_size_t offset; 1299 1300 if (b.BCflags & BCFvirtual) // skip virtual base classes 1301 continue; 1302 offset = b.BCoffset; 1303 typidx = cv4_symtypidx(b.BCbase); 1304 1305 attribute = (b.BCflags & BCFpmask); 1306 if (attribute & 4) 1307 attribute = 1; 1308 else 1309 attribute = 4 - attribute; 1310 1311 TOWORD(p,LF_BCLASS); 1312 if (config.fulltypes == CV4) 1313 { TOWORD(p + 2,typidx); 1314 TOWORD(p + 4,attribute); 1315 p += 6; 1316 } 1317 else 1318 { TOLONG(p + 4,typidx); 1319 TOWORD(p + 2,attribute); 1320 p += 8; 1321 } 1322 1323 cv4_storenumeric(p,offset); 1324 p += cv4_numericbytes(offset); 1325 } 1326 1327 // Now direct followed by indirect virtual base classes 1328 i = LF_VBCLASS; 1329 do 1330 { 1331 for (b = st.Svirtbase; b; b = b.BCnext) 1332 { targ_size_t vbpoff,vboff; 1333 type *vbptype; // type of virtual base pointer 1334 idx_t vbpidx; 1335 1336 if (baseclass_find(st.Sbase,b.BCbase)) // if direct vbase 1337 { if (i == LF_IVBCLASS) 1338 continue; 1339 } 1340 else 1341 { if (i == LF_VBCLASS) 1342 continue; 1343 } 1344 1345 typidx = cv4_symtypidx(b.BCbase); 1346 1347 vbptype = type_allocn(TYarray,tstypes[TYint]); 1348 vbptype.Tflags |= TFsizeunknown; 1349 vbptype = newpointer(vbptype); 1350 vbptype.Tcount++; 1351 vbpidx = cv4_typidx(vbptype); 1352 type_free(vbptype); 1353 1354 attribute = (b.BCflags & BCFpmask); 1355 if (attribute & 4) 1356 attribute = 1; 1357 else 1358 attribute = 4 - attribute; 1359 1360 vbpoff = st.Svbptr_off; 1361 vboff = b.BCvbtbloff / _tysize[TYint]; 1362 1363 if (config.fulltypes == CV4) 1364 { TOWORD(p,i); 1365 TOWORD(p + 2,typidx); 1366 TOWORD(p + 4,vbpidx); 1367 TOWORD(p + 6,attribute); 1368 p += 8; 1369 } 1370 else 1371 { TOWORD(p,i); 1372 TOLONG(p + 4,typidx); // btype 1373 TOLONG(p + 8,vbpidx); // vbtype 1374 TOWORD(p + 2,attribute); 1375 p += 12; 1376 } 1377 1378 cv4_storenumeric(p,vbpoff); 1379 p += cv4_numericbytes(vbpoff); 1380 cv4_storenumeric(p,vboff); 1381 p += cv4_numericbytes(vboff); 1382 } 1383 i ^= LF_VBCLASS ^ LF_IVBCLASS; // toggle between them 1384 } while (i != LF_VBCLASS); 1385 1386 // Now friend classes 1387 foreach (sl; ListRange(s.Sstruct.Sfriendclass)) 1388 { Symbol *sf = list_symbol(sl); 1389 1390 symbol_debug(sf); 1391 typidx = cv4_symtypidx(sf); 1392 if (config.fulltypes == CV4) 1393 { TOWORD(p,LF_FRIENDCLS); 1394 TOWORD(p + 2,typidx); 1395 p += 4; 1396 } 1397 else 1398 { TOLONG(p,LF_FRIENDCLS); 1399 TOLONG(p + 4,typidx); 1400 p += 8; 1401 } 1402 } 1403 1404 // Now friend functions 1405 foreach (sl; ListRange(s.Sstruct.Sfriendfuncs)) 1406 { Symbol *sf = list_symbol(sl); 1407 1408 symbol_debug(sf); 1409 if (sf.Sclass == SCfunctempl) 1410 continue; 1411 typidx = cv4_symtypidx(sf); 1412 TOWORD(p,LF_FRIENDFCN); 1413 if (config.fulltypes == CV4) 1414 { TOWORD(p + 2,typidx); 1415 p += 4; 1416 } 1417 else 1418 { TOLONG(p + 2,typidx); 1419 p += 6; 1420 } 1421 p += cv_namestring(p,cpp_unmangleident(sf.Sident.ptr)); 1422 } 1423 } 1424 } 1425 foreach (sl; ListRange(s.Sstruct.Sfldlst)) 1426 { Symbol *sf = list_symbol(sl); 1427 targ_size_t offset; 1428 1429 symbol_debug(sf); 1430 const(char)* sfid = sf.Sident.ptr; 1431 switch (sf.Sclass) 1432 { 1433 case SCfield: 1434 { debtyp_t *db; 1435 1436 if (config.fulltypes == CV4) 1437 { db = debtyp_alloc(6); 1438 TOWORD(db.data.ptr,LF_BITFIELD); 1439 db.data.ptr[2] = sf.Swidth; 1440 db.data.ptr[3] = sf.Sbit; 1441 TOWORD(db.data.ptr + 4,cv4_symtypidx(sf)); 1442 } 1443 else 1444 { db = debtyp_alloc(8); 1445 TOWORD(db.data.ptr,LF_BITFIELD); 1446 db.data.ptr[6] = sf.Swidth; 1447 db.data.ptr[7] = sf.Sbit; 1448 TOLONG(db.data.ptr + 2,cv4_symtypidx(sf)); 1449 } 1450 typidx = cv_debtyp(db); 1451 goto L3; 1452 } 1453 1454 case SCmember: 1455 typidx = cv4_symtypidx(sf); 1456 L3: 1457 version (SCPP) 1458 { 1459 if (CPP && sf == s.Sstruct.Svptr) 1460 { 1461 if (config.fulltypes == CV4) 1462 { TOWORD(p,LF_VFUNCTAB); 1463 TOWORD(p + 2,typidx); 1464 p += 4; 1465 } 1466 else 1467 { TOLONG(p,LF_VFUNCTAB); // 0 fill 2 bytes 1468 TOLONG(p + 4,typidx); 1469 p += 8; 1470 } 1471 break; 1472 } 1473 } 1474 offset = sf.Smemoff; 1475 TOWORD(p,LF_MEMBER); 1476 version (SCPP) 1477 { 1478 attribute = CPP ? SFLtoATTR(sf.Sflags) : 0; 1479 assert((attribute & ~3) == 0); 1480 } 1481 else 1482 { 1483 attribute = 0; 1484 } 1485 if (config.fulltypes == CV4) 1486 { TOWORD(p + 2,typidx); 1487 TOWORD(p + 4,attribute); 1488 p += 6; 1489 } 1490 else 1491 { TOLONG(p + 4,typidx); 1492 TOWORD(p + 2,attribute); 1493 p += 8; 1494 } 1495 cv4_storenumeric(p,cast(uint)offset); 1496 p += cv4_numericbytes(cast(uint)offset); 1497 p += cv_namestring(p,sfid); 1498 break; 1499 1500 version (SCPP) 1501 { 1502 case SCstruct: 1503 if (sf.Sstruct.Sflags & STRanonymous) 1504 continue; 1505 if (sf.Sstruct.Sflags & STRnotagname) 1506 sfid = cpp_name_none.ptr; 1507 goto Lnest; 1508 1509 case SCenum: 1510 if (sf.Senum.SEflags & SENnotagname) 1511 sfid = cpp_name_none.ptr; 1512 goto Lnest; 1513 1514 case SCtypedef: 1515 Lnest: 1516 TOWORD(p,LF_NESTTYPE); 1517 typidx = cv4_symtypidx(sf); 1518 if (config.fulltypes == CV4) 1519 { TOWORD(p + 2,typidx); 1520 p += 4; 1521 } 1522 else 1523 { TOLONG(p + 4,typidx); 1524 p += 8; 1525 } 1526 L2: 1527 p += cv_namestring(p,sfid); 1528 break; 1529 1530 case SCextern: 1531 case SCcomdef: 1532 case SCglobal: 1533 case SCstatic: 1534 case SCinline: 1535 case SCsinline: 1536 case SCeinline: 1537 case SCcomdat: 1538 if (tyfunc(sf.ty())) 1539 { int count2; 1540 1541 typidx = cv4_methodlist(sf,&count2); 1542 if (!typidx) 1543 break; 1544 sfid = cv4_prettyident(sf); 1545 TOWORD(p,LF_METHOD); 1546 TOWORD(p + 2,count2); 1547 p += 4; 1548 TOIDX(p,typidx); 1549 p += cgcv.sz_idx; 1550 goto L2; 1551 } 1552 else 1553 { 1554 TOWORD(p,LF_STMEMBER); 1555 typidx = cv4_symtypidx(sf); 1556 attribute = SFLtoATTR(sf.Sflags); 1557 if (config.fulltypes == CV4) 1558 { TOWORD(p + 2,typidx); 1559 TOWORD(p + 4,attribute); 1560 p += 6; 1561 } 1562 else 1563 { TOLONG(p + 4,typidx); 1564 TOWORD(p + 2,attribute); 1565 p += 8; 1566 } 1567 goto L2; 1568 } 1569 break; 1570 } 1571 1572 default: 1573 continue; 1574 } 1575 } 1576 //printf("fnamelen = %d, p-dt.data = %d\n",fnamelen,p-dt.data); 1577 assert(p - dt.data.ptr == fnamelen); 1578 if (config.fulltypes == CV4) 1579 TOWORD(d.data.ptr + 4,cv_debtyp(dt)); 1580 else 1581 TOLONG(d.data.ptr + 6,cv_debtyp(dt)); 1582 1583 static if (SYMDEB_TDB) 1584 { 1585 if (config.fulltypes == CVTDB) 1586 { 1587 s.Stypidx = cv_debtyp(d); 1588 reset_symbuf.write(&s, (s).sizeof); 1589 } 1590 } 1591 version (SCPP) 1592 { 1593 if (CPP) 1594 { 1595 symbol_debug(s); 1596 if (st.Sflags & STRglobal) 1597 list_prepend(&cgcv.list,s); 1598 else 1599 cv4_outsym(s); 1600 } 1601 } 1602 return s.Stypidx; 1603 } 1604 1605 /**************************** 1606 * Return type index of enum. 1607 */ 1608 1609 version (SCPP) 1610 { 1611 1612 private uint cv4_enum(Symbol *s) 1613 { 1614 debtyp_t* d,dt; 1615 uint nfields,fnamelen; 1616 uint len; 1617 type *t; 1618 type *tbase; 1619 uint property; 1620 uint attribute; 1621 int i; 1622 char *id; 1623 1624 symbol_debug(s); 1625 if (s.Stypidx) // if already converted 1626 { //assert(s.Stypidx - cgcv.deb_offset < debtyp.length); 1627 return s.Stypidx; 1628 } 1629 1630 //printf("cv4_enum(%s)\n",s.Sident.ptr); 1631 t = s.Stype; 1632 type_debug(t); 1633 tbase = t.Tnext; 1634 property = 0; 1635 if (s.Senum.SEflags & SENforward) 1636 property |= 0x80; // enum is forward referenced 1637 1638 id = s.Sident.ptr; 1639 if (s.Senum.SEflags & SENnotagname) 1640 id = cpp_name_none.ptr; 1641 if (config.fulltypes == CV4) 1642 { len = 10; 1643 d = debtyp_alloc(len + cv_stringbytes(id)); 1644 TOWORD(d.data.ptr,LF_ENUM); 1645 TOWORD(d.data.ptr + 4,cv4_typidx(tbase)); 1646 TOWORD(d.data.ptr + 8,property); 1647 } 1648 else 1649 { len = 14; 1650 d = debtyp_alloc(len + cv_stringbytes(id)); 1651 TOWORD(d.data.ptr,LF_ENUM); 1652 TOLONG(d.data.ptr + 6,cv4_typidx(tbase)); 1653 TOWORD(d.data.ptr + 4,property); 1654 } 1655 len += cv_namestring(d.data.ptr + len,id); 1656 1657 // Assign a number to prevent infinite recursion if an enum member 1658 // references the same enum. 1659 if (config.fulltypes == CVTDB) 1660 { 1661 static if (SYMDEB_TDB) 1662 { 1663 debtyp_t *df; 1664 1665 TOWORD(d.data.ptr + 2,0); 1666 TOWORD(d.data.ptr + 6,0); 1667 debtyp_check(d); 1668 s.Stypidx = tdb_typidx(&d.length); // forward reference it 1669 } 1670 } 1671 else 1672 { 1673 d.length = 0; // so cv_debtyp() will allocate new 1674 s.Stypidx = cv_debtyp(d); 1675 d.length = cast(ushort)len; // restore length 1676 } 1677 reset_symbuf.write((&s)[0 .. 1]); 1678 1679 // Compute the number of fields, and the length of the fieldlist record 1680 nfields = 0; 1681 fnamelen = 2; 1682 foreach (sl; ListRange(s.Senum.SEenumlist)) 1683 { Symbol *sf = list_symbol(sl); 1684 uint value; 1685 1686 symbol_debug(sf); 1687 value = cast(uint)el_tolongt(sf.Svalue); 1688 nfields++; 1689 fnamelen += 4 + cv4_numericbytes(value) + cv_stringbytes(sf.Sident.ptr); 1690 } 1691 1692 TOWORD(d.data.ptr + 2,nfields); 1693 1694 // If forward reference, then field list is 0 1695 if (s.Senum.SEflags & SENforward) 1696 { 1697 TOWORD(d.data.ptr + 6,0); 1698 return s.Stypidx; 1699 } 1700 1701 // Generate fieldlist type record 1702 dt = debtyp_alloc(fnamelen); 1703 TOWORD(dt.data.ptr,LF_FIELDLIST); 1704 1705 // And fill it in 1706 i = 2; 1707 foreach (sl; ListRange(s.Senum.SEenumlist)) 1708 { Symbol *sf = list_symbol(sl); 1709 uint value; 1710 1711 symbol_debug(sf); 1712 value = cast(uint)el_tolongt(sf.Svalue); 1713 TOWORD(dt.data.ptr + i,LF_ENUMERATE); 1714 attribute = SFLtoATTR(sf.Sflags); 1715 TOWORD(dt.data.ptr + i + 2,attribute); 1716 cv4_storenumeric(dt.data.ptr + i + 4,value); 1717 i += 4 + cv4_numericbytes(value); 1718 i += cv_namestring(dt.data.ptr + i,sf.Sident.ptr); 1719 1720 // If enum is not a member of a class, output enum members as constants 1721 if (!isclassmember(s)) 1722 { symbol_debug(sf); 1723 cv4_outsym(sf); 1724 } 1725 } 1726 assert(i == fnamelen); 1727 if (config.fulltypes == CV4) 1728 TOWORD(d.data.ptr + 6,cv_debtyp(dt)); 1729 else 1730 TOLONG(d.data.ptr + 10,cv_debtyp(dt)); 1731 1732 symbol_debug(s); 1733 if (CPP) 1734 cv4_outsym(s); 1735 return s.Stypidx; 1736 } 1737 1738 } 1739 else 1740 { 1741 private uint cv4_fwdenum(type* t) 1742 { 1743 Symbol* s = t.Ttag; 1744 1745 // write a forward reference enum record that is enough for the linker to 1746 // fold with original definition from EnumDeclaration 1747 uint bty = dttab4[tybasic(t.Tnext.Tty)]; 1748 const id = prettyident(s); 1749 uint len = config.fulltypes == CV8 ? 14 : 10; 1750 debtyp_t* d = debtyp_alloc(len + cv_stringbytes(id)); 1751 switch (config.fulltypes) 1752 { 1753 case CV8: 1754 TOWORD(d.data.ptr, LF_ENUM_V3); 1755 TOLONG(d.data.ptr + 2, 0); // count 1756 TOWORD(d.data.ptr + 4, 0x80); // property : forward reference 1757 TOLONG(d.data.ptr + 6, bty); // memtype 1758 TOLONG(d.data.ptr + 10, 0); // fieldlist 1759 break; 1760 1761 case CV4: 1762 TOWORD(d.data.ptr,LF_ENUM); 1763 TOWORD(d.data.ptr + 2, 0); // count 1764 TOWORD(d.data.ptr + 4, bty); // memtype 1765 TOLONG(d.data.ptr + 6, 0); // fieldlist 1766 TOWORD(d.data.ptr + 8, 0x80); // property : forward reference 1767 break; 1768 1769 default: 1770 assert(0); 1771 } 1772 cv_namestring(d.data.ptr + len, id); 1773 s.Stypidx = cv_debtyp(d); 1774 return s.Stypidx; 1775 } 1776 1777 } 1778 /************************************************ 1779 * Return 'calling convention' type of function. 1780 */ 1781 1782 ubyte cv4_callconv(type *t) 1783 { ubyte call; 1784 1785 switch (tybasic(t.Tty)) 1786 { 1787 case TYffunc: call = 1; break; 1788 case TYfpfunc: call = 3; break; 1789 case TYf16func: call = 3; break; 1790 case TYfsfunc: call = 8; break; 1791 case TYnsysfunc: call = 9; break; 1792 case TYfsysfunc: call = 10; break; 1793 case TYnfunc: call = 0; break; 1794 case TYnpfunc: call = 2; break; 1795 case TYnsfunc: call = 7; break; 1796 case TYifunc: call = 1; break; 1797 case TYjfunc: call = 2; break; 1798 case TYmfunc: call = 11; break; // this call 1799 default: 1800 assert(0); 1801 } 1802 return call; 1803 } 1804 1805 /********************************************** 1806 * Return type index for the type of a symbol. 1807 */ 1808 1809 version (MARS) 1810 { 1811 1812 private uint cv4_symtypidx(Symbol *s) 1813 { 1814 return cv4_typidx(s.Stype); 1815 } 1816 1817 } 1818 1819 version (SCPP) 1820 { 1821 1822 private uint cv4_symtypidx(Symbol *s) 1823 { type *t; 1824 debtyp_t *d; 1825 ubyte *p; 1826 1827 if (!CPP) 1828 return cv4_typidx(s.Stype); 1829 symbol_debug(s); 1830 if (isclassmember(s)) 1831 { t = s.Stype; 1832 if (tyfunc(t.Tty)) 1833 { param_t *pa; 1834 uint nparam; 1835 idx_t paramidx; 1836 idx_t thisidx; 1837 uint u; 1838 func_t *f; 1839 ubyte call; 1840 1841 // It's a member function, which gets a special type record 1842 1843 f = s.Sfunc; 1844 if (f.Fflags & Fstatic) 1845 thisidx = dttab4[TYvoid]; 1846 else 1847 { type *tthis = cpp_thistype(s.Stype,cast(Classsym *)s.Sscope); 1848 1849 thisidx = cv4_typidx(tthis); 1850 type_free(tthis); 1851 } 1852 1853 paramidx = cv4_arglist(t,&nparam); 1854 call = cv4_callconv(t); 1855 1856 if (config.fulltypes == CV4) 1857 { 1858 d = debtyp_alloc(18); 1859 p = d.data.ptr; 1860 TOWORD(p,LF_MFUNCTION); 1861 TOWORD(p + 2,cv4_typidx(t.Tnext)); 1862 TOWORD(p + 4,cv4_symtypidx(s.Sscope)); 1863 TOWORD(p + 6,thisidx); 1864 p[8] = call; 1865 p[9] = 0; // reserved 1866 TOWORD(p + 10,nparam); 1867 TOWORD(p + 12,paramidx); 1868 TOLONG(p + 14,0); // thisadjust 1869 } 1870 else 1871 { 1872 d = debtyp_alloc(26); 1873 p = d.data.ptr; 1874 TOWORD(p,LF_MFUNCTION); 1875 TOLONG(p + 2,cv4_typidx(t.Tnext)); 1876 TOLONG(p + 6,cv4_symtypidx(s.Sscope)); 1877 TOLONG(p + 10,thisidx); 1878 p[14] = call; 1879 p[15] = 0; // reserved 1880 TOWORD(p + 16,nparam); 1881 TOLONG(p + 18,paramidx); 1882 TOLONG(p + 22,0); // thisadjust 1883 } 1884 return cv_debtyp(d); 1885 } 1886 } 1887 return cv4_typidx(s.Stype); 1888 } 1889 1890 } 1891 1892 /*********************************** 1893 * Return CV4 type index for a type. 1894 */ 1895 1896 uint cv4_typidx(type *t) 1897 { uint typidx; 1898 uint u; 1899 uint next; 1900 uint key; 1901 debtyp_t *d; 1902 targ_size_t size; 1903 tym_t tym; 1904 tym_t tycv; 1905 tym_t tymnext; 1906 type *tv; 1907 uint dt; 1908 uint attribute; 1909 ubyte call; 1910 1911 //printf("cv4_typidx(%p)\n",t); 1912 if (!t) 1913 return dttab4[TYint]; // assume int 1914 type_debug(t); 1915 next = cv4_typidx(t.Tnext); 1916 tycv = t.Tty; 1917 tym = tybasic(tycv); 1918 tycv &= mTYconst | mTYvolatile | mTYimmutable; 1919 attribute = 0; 1920 L1: 1921 dt = dttab4[tym]; 1922 switch (tym) 1923 { 1924 case TYllong: 1925 if (t.Tnext) 1926 goto Ldelegate; 1927 assert(dt); 1928 typidx = dt; 1929 break; 1930 1931 case TYullong: 1932 if (t.Tnext) 1933 goto Ldarray; 1934 assert(dt); 1935 typidx = dt; 1936 break; 1937 1938 case TYvoid: 1939 case TYchar: 1940 case TYschar: 1941 case TYuchar: 1942 case TYchar16: 1943 case TYshort: 1944 case TYushort: 1945 case TYint: 1946 case TYuint: 1947 case TYulong: 1948 case TYlong: 1949 case TYfloat: 1950 case TYdouble: 1951 case TYdouble_alias: 1952 case TYldouble: 1953 case TYifloat: 1954 case TYidouble: 1955 case TYildouble: 1956 case TYcfloat: 1957 case TYcdouble: 1958 case TYcldouble: 1959 case TYbool: 1960 case TYwchar_t: 1961 case TYdchar: 1962 assert(dt); 1963 typidx = dt; 1964 break; 1965 1966 case TYnptr: 1967 case TYimmutPtr: 1968 case TYsharePtr: 1969 case TYrestrictPtr: 1970 version (MARS) 1971 { 1972 if (t.Tkey) 1973 goto Laarray; 1974 } 1975 goto Lptr; 1976 case TYsptr: 1977 case TYcptr: 1978 case TYfgPtr: 1979 Lptr: 1980 attribute |= I32 ? 10 : 0; goto L2; 1981 1982 case TYfptr: 1983 case TYvptr: attribute |= I32 ? 11 : 1; goto L2; 1984 case TYhptr: attribute |= 2; goto L2; 1985 1986 L2: 1987 if (config.fulltypes == CV4) 1988 { 1989 // This is a hack to duplicate bugs in VC, so that the VC 1990 // debugger will work. 1991 tymnext = t.Tnext ? t.Tnext.Tty : TYint; 1992 if (tymnext & (mTYconst | mTYimmutable | mTYvolatile) && 1993 !tycv && 1994 tyarithmetic(tymnext) && 1995 !(attribute & 0xE0) 1996 ) 1997 { 1998 typidx = dt | dttab4[tybasic(tymnext)]; 1999 break; 2000 } 2001 } 2002 if ((next & 0xFF00) == 0 && !(attribute & 0xE0)) 2003 typidx = next | dt; 2004 else 2005 { 2006 if (tycv & (mTYconst | mTYimmutable)) 2007 attribute |= 0x400; 2008 if (tycv & mTYvolatile) 2009 attribute |= 0x200; 2010 tycv = 0; 2011 switch (config.fulltypes) 2012 { 2013 case CV4: 2014 d = debtyp_alloc(6); 2015 TOWORD(d.data.ptr,LF_POINTER); 2016 TOWORD(d.data.ptr + 2,attribute); 2017 TOWORD(d.data.ptr + 4,next); 2018 break; 2019 2020 case CV8: 2021 d = debtyp_alloc(10); 2022 TOWORD(d.data.ptr,0x1002); 2023 TOLONG(d.data.ptr + 2,next); 2024 // see https://github.com/Microsoft/microsoft-pdb/blob/master/include/cvinfo.h#L1514 2025 // add size and pointer type (PTR_64 or PTR_NEAR32) 2026 attribute |= (I64 ? (8 << 13) | 0xC : (4 << 13) | 0xA); 2027 // convert reference to r-value reference to remove & from type display in debugger 2028 if (attribute & 0x20) 2029 attribute |= 0x80; 2030 TOLONG(d.data.ptr + 6,attribute); 2031 break; 2032 2033 default: 2034 d = debtyp_alloc(10); 2035 TOWORD(d.data.ptr,LF_POINTER); 2036 TOLONG(d.data.ptr + 2,attribute); 2037 TOLONG(d.data.ptr + 6,next); 2038 break; 2039 } 2040 typidx = cv_debtyp(d); 2041 } 2042 break; 2043 2044 Ldarray: 2045 switch (config.fulltypes) 2046 { 2047 version (MARS) 2048 { 2049 case CV8: 2050 { 2051 typidx = cv8_darray(t, next); 2052 break; 2053 } 2054 } 2055 case CV4: 2056 static if (1) 2057 { 2058 d = debtyp_alloc(12); 2059 TOWORD(d.data.ptr, LF_OEM); 2060 TOWORD(d.data.ptr + 2, OEM); 2061 TOWORD(d.data.ptr + 4, 1); // 1 = dynamic array 2062 TOWORD(d.data.ptr + 6, 2); // count of type indices to follow 2063 TOWORD(d.data.ptr + 8, 0x12); // index type, T_LONG 2064 TOWORD(d.data.ptr + 10, next); // element type 2065 } 2066 else 2067 { 2068 d = debtyp_alloc(6); 2069 TOWORD(d.data.ptr,LF_DYN_ARRAY); 2070 TOWORD(d.data.ptr + 2, 0x12); // T_LONG 2071 TOWORD(d.data.ptr + 4, next); 2072 } 2073 typidx = cv_debtyp(d); 2074 break; 2075 2076 default: 2077 assert(0); 2078 } 2079 2080 break; 2081 2082 Laarray: 2083 version (MARS) 2084 { 2085 key = cv4_typidx(t.Tkey); 2086 switch (config.fulltypes) 2087 { 2088 case CV8: 2089 typidx = cv8_daarray(t, key, next); 2090 break; 2091 2092 case CV4: 2093 static if (1) 2094 { 2095 d = debtyp_alloc(12); 2096 TOWORD(d.data.ptr, LF_OEM); 2097 TOWORD(d.data.ptr + 2, OEM); 2098 TOWORD(d.data.ptr + 4, 2); // 2 = associative array 2099 TOWORD(d.data.ptr + 6, 2); // count of type indices to follow 2100 TOWORD(d.data.ptr + 8, key); // key type 2101 TOWORD(d.data.ptr + 10, next); // element type 2102 } 2103 else 2104 { 2105 d = debtyp_alloc(6); 2106 TOWORD(d.data.ptr,LF_ASSOC_ARRAY); 2107 TOWORD(d.data.ptr + 2, key); // key type 2108 TOWORD(d.data.ptr + 4, next); // element type 2109 } 2110 typidx = cv_debtyp(d); 2111 break; 2112 2113 default: 2114 assert(0); 2115 } 2116 } 2117 break; 2118 2119 Ldelegate: 2120 switch (config.fulltypes) 2121 { 2122 version (MARS) 2123 { 2124 case CV8: 2125 typidx = cv8_ddelegate(t, next); 2126 break; 2127 } 2128 2129 case CV4: 2130 tv = type_fake(TYnptr); 2131 tv.Tcount++; 2132 key = cv4_typidx(tv); 2133 type_free(tv); 2134 static if (1) 2135 { 2136 d = debtyp_alloc(12); 2137 TOWORD(d.data.ptr, LF_OEM); 2138 TOWORD(d.data.ptr + 2, OEM); 2139 TOWORD(d.data.ptr + 4, 3); // 3 = delegate 2140 TOWORD(d.data.ptr + 6, 2); // count of type indices to follow 2141 TOWORD(d.data.ptr + 8, key); // type of 'this', which is void* 2142 TOWORD(d.data.ptr + 10, next); // function type 2143 } 2144 else 2145 { 2146 d = debtyp_alloc(6); 2147 TOWORD(d.data.ptr,LF_DELEGATE); 2148 TOWORD(d.data.ptr + 2, key); // type of 'this', which is void* 2149 TOWORD(d.data.ptr + 4, next); // function type 2150 } 2151 typidx = cv_debtyp(d); 2152 break; 2153 2154 default: 2155 assert(0); 2156 } 2157 break; 2158 2159 case TYcent: 2160 if (t.Tnext) 2161 goto Ldelegate; 2162 assert(dt); 2163 typidx = dt; 2164 break; 2165 2166 case TYucent: 2167 if (t.Tnext) 2168 goto Ldarray; 2169 assert(dt); 2170 typidx = dt; 2171 break; 2172 2173 case TYarray: 2174 { if (t.Tflags & TFsizeunknown) 2175 size = 0; // don't complain if don't know size 2176 else 2177 size = type_size(t); 2178 Larray: 2179 u = cv4_numericbytes(cast(uint)size); 2180 uint idxtype = I32 ? 0x12 : 0x11; // T_LONG : T_SHORT 2181 if (I64) 2182 idxtype = 0x23; // T_UQUAD 2183 if(next == dttab4[TYvoid]) // do not encode void[n], this confuses the debugger 2184 next = dttab4[TYuchar]; // use ubyte instead 2185 switch (config.fulltypes) 2186 { 2187 case CV8: 2188 d = debtyp_alloc(10 + u + 1); 2189 TOWORD(d.data.ptr,0x1503); 2190 TOLONG(d.data.ptr + 2,next); 2191 TOLONG(d.data.ptr + 6,idxtype); 2192 d.data.ptr[10 + u] = 0; // no name 2193 cv4_storenumeric(d.data.ptr + 10,cast(uint)size); 2194 break; 2195 2196 case CV4: 2197 d = debtyp_alloc(6 + u + 1); 2198 TOWORD(d.data.ptr,LF_ARRAY); 2199 TOWORD(d.data.ptr + 2,next); 2200 TOWORD(d.data.ptr + 4,idxtype); 2201 d.data.ptr[6 + u] = 0; // no name 2202 cv4_storenumeric(d.data.ptr + 6,cast(uint)size); 2203 break; 2204 2205 default: 2206 d = debtyp_alloc(10 + u + 1); 2207 TOWORD(d.data.ptr,LF_ARRAY); 2208 TOLONG(d.data.ptr + 2,next); 2209 TOLONG(d.data.ptr + 6,idxtype); 2210 d.data.ptr[10 + u] = 0; // no name 2211 cv4_storenumeric(d.data.ptr + 10,cast(uint)size); 2212 break; 2213 } 2214 typidx = cv_debtyp(d); 2215 break; 2216 } 2217 2218 case TYffunc: 2219 case TYfpfunc: 2220 case TYf16func: 2221 case TYfsfunc: 2222 case TYnsysfunc: 2223 case TYfsysfunc: 2224 case TYnfunc: 2225 case TYnpfunc: 2226 case TYnsfunc: 2227 case TYmfunc: 2228 case TYjfunc: 2229 case TYifunc: 2230 { 2231 param_t *p; 2232 uint nparam; 2233 idx_t paramidx; 2234 2235 call = cv4_callconv(t); 2236 paramidx = cv4_arglist(t,&nparam); 2237 2238 // Construct an LF_PROCEDURE 2239 switch (config.fulltypes) 2240 { 2241 case CV8: 2242 d = debtyp_alloc(2 + 4 + 1 + 1 + 2 + 4); 2243 TOWORD(d.data.ptr,LF_PROCEDURE_V2); 2244 TOLONG(d.data.ptr + 2,next); // return type 2245 d.data.ptr[6] = call; 2246 d.data.ptr[7] = 0; // reserved 2247 TOWORD(d.data.ptr + 8,nparam); 2248 TOLONG(d.data.ptr + 10,paramidx); 2249 break; 2250 2251 case CV4: 2252 d = debtyp_alloc(2 + 2 + 1 + 1 + 2 + 2); 2253 TOWORD(d.data.ptr,LF_PROCEDURE); 2254 TOWORD(d.data.ptr + 2,next); // return type 2255 d.data.ptr[4] = call; 2256 d.data.ptr[5] = 0; // reserved 2257 TOWORD(d.data.ptr + 6,nparam); 2258 TOWORD(d.data.ptr + 8,paramidx); 2259 break; 2260 2261 default: 2262 d = debtyp_alloc(2 + 4 + 1 + 1 + 2 + 4); 2263 TOWORD(d.data.ptr,LF_PROCEDURE); 2264 TOLONG(d.data.ptr + 2,next); // return type 2265 d.data.ptr[6] = call; 2266 d.data.ptr[7] = 0; // reserved 2267 TOWORD(d.data.ptr + 8,nparam); 2268 TOLONG(d.data.ptr + 10,paramidx); 2269 break; 2270 } 2271 2272 typidx = cv_debtyp(d); 2273 break; 2274 } 2275 2276 case TYstruct: 2277 { 2278 if (config.fulltypes == CV8) 2279 { 2280 version (MARS) 2281 { 2282 typidx = cv8_fwdref(t.Ttag); 2283 } 2284 } 2285 else 2286 { 2287 int foo = t.Ttag.Stypidx; 2288 typidx = cv4_struct(t.Ttag,0); 2289 //printf("struct '%s' %x %x\n", t.Ttag.Sident.ptr, foo, typidx); 2290 } 2291 break; 2292 } 2293 2294 case TYenum: 2295 if (CPP) 2296 { 2297 version (SCPP) 2298 { 2299 typidx = cv4_enum(t.Ttag); 2300 } 2301 } 2302 else 2303 typidx = cv4_fwdenum(t); 2304 break; 2305 2306 version (SCPP) 2307 { 2308 case TYvtshape: 2309 { uint count; 2310 ubyte *p; 2311 ubyte descriptor; 2312 2313 count = 1 + list_nitems(t.Ttag.Sstruct.Svirtual); 2314 d = debtyp_alloc(4 + ((count + 1) >> 1)); 2315 p = d.data.ptr; 2316 TOWORD(p,LF_VTSHAPE); 2317 TOWORD(p + 2,count); 2318 descriptor = I32 ? 0x55 : (LARGECODE ? 0x11 : 0); 2319 memset(p + 4,descriptor,(count + 1) >> 1); 2320 2321 typidx = cv_debtyp(d); 2322 break; 2323 } 2324 2325 case TYref: 2326 case TYnref: 2327 case TYfref: 2328 attribute |= 0x20; // indicate reference pointer 2329 goto case; 2330 2331 case TYmemptr: 2332 tym = tybasic(tym_conv(t)); // convert to C data type 2333 goto L1; // and try again 2334 } 2335 2336 version (MARS) 2337 { 2338 case TYref: 2339 case TYnref: 2340 attribute |= 0x20; // indicate reference pointer 2341 tym = TYnptr; // convert to C data type 2342 goto L1; // and try again 2343 } 2344 2345 case TYnullptr: 2346 tym = TYnptr; 2347 next = cv4_typidx(tstypes[TYvoid]); // rewrite as void* 2348 t = tspvoid; 2349 goto L1; 2350 2351 // vector types 2352 case TYfloat4: size = 16; next = dttab4[TYfloat]; goto Larray; 2353 case TYdouble2: size = 16; next = dttab4[TYdouble]; goto Larray; 2354 case TYschar16: size = 16; next = dttab4[TYschar]; goto Larray; 2355 case TYuchar16: size = 16; next = dttab4[TYuchar]; goto Larray; 2356 case TYshort8: size = 16; next = dttab4[TYshort]; goto Larray; 2357 case TYushort8: size = 16; next = dttab4[TYushort]; goto Larray; 2358 case TYlong4: size = 16; next = dttab4[TYlong]; goto Larray; 2359 case TYulong4: size = 16; next = dttab4[TYulong]; goto Larray; 2360 case TYllong2: size = 16; next = dttab4[TYllong]; goto Larray; 2361 case TYullong2: size = 16; next = dttab4[TYullong]; goto Larray; 2362 2363 case TYfloat8: size = 32; next = dttab4[TYfloat]; goto Larray; 2364 case TYdouble4: size = 32; next = dttab4[TYdouble]; goto Larray; 2365 case TYschar32: size = 32; next = dttab4[TYschar]; goto Larray; 2366 case TYuchar32: size = 32; next = dttab4[TYuchar]; goto Larray; 2367 case TYshort16: size = 32; next = dttab4[TYshort]; goto Larray; 2368 case TYushort16: size = 32; next = dttab4[TYushort]; goto Larray; 2369 case TYlong8: size = 32; next = dttab4[TYlong]; goto Larray; 2370 case TYulong8: size = 32; next = dttab4[TYulong]; goto Larray; 2371 case TYllong4: size = 32; next = dttab4[TYllong]; goto Larray; 2372 case TYullong4: size = 32; next = dttab4[TYullong]; goto Larray; 2373 2374 case TYfloat16: size = 64; next = dttab4[TYfloat]; goto Larray; 2375 case TYdouble8: size = 64; next = dttab4[TYdouble]; goto Larray; 2376 case TYschar64: size = 64; next = dttab4[TYschar]; goto Larray; 2377 case TYuchar64: size = 64; next = dttab4[TYuchar]; goto Larray; 2378 case TYshort32: size = 64; next = dttab4[TYshort]; goto Larray; 2379 case TYushort32: size = 64; next = dttab4[TYushort]; goto Larray; 2380 case TYlong16: size = 64; next = dttab4[TYlong]; goto Larray; 2381 case TYulong16: size = 64; next = dttab4[TYulong]; goto Larray; 2382 case TYllong8: size = 64; next = dttab4[TYllong]; goto Larray; 2383 case TYullong8: size = 64; next = dttab4[TYullong]; goto Larray; 2384 2385 default: 2386 debug 2387 WRTYxx(tym); 2388 2389 assert(0); 2390 } 2391 2392 // Add in const and/or volatile modifiers 2393 if (tycv & (mTYconst | mTYimmutable | mTYvolatile)) 2394 { uint modifier; 2395 2396 modifier = (tycv & (mTYconst | mTYimmutable)) ? 1 : 0; 2397 modifier |= (tycv & mTYvolatile) ? 2 : 0; 2398 switch (config.fulltypes) 2399 { 2400 case CV8: 2401 d = debtyp_alloc(8); 2402 TOWORD(d.data.ptr,0x1001); 2403 TOLONG(d.data.ptr + 2,typidx); 2404 TOWORD(d.data.ptr + 6,modifier); 2405 break; 2406 2407 case CV4: 2408 d = debtyp_alloc(6); 2409 TOWORD(d.data.ptr,LF_MODIFIER); 2410 TOWORD(d.data.ptr + 2,modifier); 2411 TOWORD(d.data.ptr + 4,typidx); 2412 break; 2413 2414 default: 2415 d = debtyp_alloc(10); 2416 TOWORD(d.data.ptr,LF_MODIFIER); 2417 TOLONG(d.data.ptr + 2,modifier); 2418 TOLONG(d.data.ptr + 6,typidx); 2419 break; 2420 } 2421 typidx = cv_debtyp(d); 2422 } 2423 2424 assert(typidx); 2425 return typidx; 2426 } 2427 2428 /****************************************** 2429 * Write out symbol s. 2430 */ 2431 2432 private void cv4_outsym(Symbol *s) 2433 { 2434 uint len; 2435 type *t; 2436 uint length; 2437 uint u; 2438 tym_t tym; 2439 const(char)* id; 2440 ubyte *debsym = null; 2441 ubyte[64] buf = void; 2442 2443 //printf("cv4_outsym(%s)\n",s.Sident.ptr); 2444 symbol_debug(s); 2445 version (MARS) 2446 { 2447 if (s.Sflags & SFLnodebug) 2448 return; 2449 } 2450 t = s.Stype; 2451 type_debug(t); 2452 tym = tybasic(t.Tty); 2453 if (tyfunc(tym) && s.Sclass != SCtypedef) 2454 { int framedatum,targetdatum,fd; 2455 char idfree; 2456 idx_t typidx; 2457 2458 if (s != funcsym_p) 2459 return; 2460 version (SCPP) 2461 { 2462 if (CPP && isclassmember(s)) // if method 2463 { Outbuffer buf2; 2464 2465 param_tostring(&buf2,s.Stype); 2466 buf2.prependBytes(cpp_prettyident(s)); 2467 char* s2 = buf2.toString(); 2468 const len2 = strlen(s2); 2469 id = cast(char*)alloca(len2 + 1); 2470 assert(id); 2471 memcpy(cast(void*)id, s2, len2 + 1); 2472 } 2473 else 2474 { 2475 id = prettyident(s); 2476 } 2477 } 2478 else 2479 { 2480 id = s.prettyIdent ? s.prettyIdent : s.Sident.ptr; 2481 } 2482 len = cv_stringbytes(id); 2483 2484 // Length of record 2485 length = 2 + 2 + 4 * 3 + _tysize[TYint] * 4 + 2 + cgcv.sz_idx + 1; 2486 debsym = (length + len <= (buf).sizeof) ? buf.ptr : cast(ubyte *) malloc(length + len); 2487 assert(debsym); 2488 memset(debsym,0,length + len); 2489 2490 // Symbol type 2491 u = (s.Sclass == SCstatic) ? S_LPROC16 : S_GPROC16; 2492 if (I32) 2493 u += S_GPROC32 - S_GPROC16; 2494 TOWORD(debsym + 2,u); 2495 2496 if (config.fulltypes == CV4) 2497 { 2498 // Offsets 2499 if (I32) 2500 { TOLONG(debsym + 16,cast(uint)s.Ssize); // proc length 2501 TOLONG(debsym + 20,cast(uint)startoffset); // debug start 2502 TOLONG(debsym + 24,cast(uint)retoffset); // debug end 2503 u = 28; // offset to fixup 2504 } 2505 else 2506 { TOWORD(debsym + 16,cast(uint)s.Ssize); // proc length 2507 TOWORD(debsym + 18,cast(uint)startoffset); // debug start 2508 TOWORD(debsym + 20,cast(uint)retoffset); // debug end 2509 u = 22; // offset to fixup 2510 } 2511 length += cv_namestring(debsym + u + _tysize[TYint] + 2 + cgcv.sz_idx + 1,id); 2512 typidx = cv4_symtypidx(s); 2513 TOIDX(debsym + u + _tysize[TYint] + 2,typidx); // proc type 2514 debsym[u + _tysize[TYint] + 2 + cgcv.sz_idx] = tyfarfunc(tym) ? 4 : 0; 2515 TOWORD(debsym,length - 2); 2516 } 2517 else 2518 { 2519 // Offsets 2520 if (I32) 2521 { TOLONG(debsym + 16 + cgcv.sz_idx,cast(uint)s.Ssize); // proc length 2522 TOLONG(debsym + 20 + cgcv.sz_idx,cast(uint)startoffset); // debug start 2523 TOLONG(debsym + 24 + cgcv.sz_idx,cast(uint)retoffset); // debug end 2524 u = 28; // offset to fixup 2525 } 2526 else 2527 { TOWORD(debsym + 16 + cgcv.sz_idx,cast(uint)s.Ssize); // proc length 2528 TOWORD(debsym + 18 + cgcv.sz_idx,cast(uint)startoffset); // debug start 2529 TOWORD(debsym + 20 + cgcv.sz_idx,cast(uint)retoffset); // debug end 2530 u = 22; // offset to fixup 2531 } 2532 u += cgcv.sz_idx; 2533 length += cv_namestring(debsym + u + _tysize[TYint] + 2 + 1,id); 2534 typidx = cv4_symtypidx(s); 2535 TOIDX(debsym + 16,typidx); // proc type 2536 debsym[u + _tysize[TYint] + 2] = tyfarfunc(tym) ? 4 : 0; 2537 TOWORD(debsym,length - 2); 2538 } 2539 2540 uint soffset = cast(uint)Offset(DEBSYM); 2541 objmod.write_bytes(SegData[DEBSYM],length,debsym); 2542 2543 // Put out fixup for function start offset 2544 objmod.reftoident(DEBSYM,soffset + u,s,0,CFseg | CFoff); 2545 } 2546 else 2547 { targ_size_t base; 2548 int reg; 2549 uint fd; 2550 uint idx1,idx2; 2551 uint value; 2552 uint fixoff; 2553 idx_t typidx; 2554 2555 typidx = cv4_typidx(t); 2556 version (MARS) 2557 { 2558 id = s.prettyIdent ? s.prettyIdent : prettyident(s); 2559 } 2560 else 2561 { 2562 id = prettyident(s); 2563 } 2564 len = cast(uint)strlen(id); 2565 debsym = (39 + IDOHD + len <= (buf).sizeof) ? buf.ptr : cast(ubyte *) malloc(39 + IDOHD + len); 2566 assert(debsym); 2567 switch (s.Sclass) 2568 { 2569 case SCparameter: 2570 case SCregpar: 2571 if (s.Sfl == FLreg) 2572 { 2573 s.Sfl = FLpara; 2574 cv4_outsym(s); 2575 s.Sfl = FLreg; 2576 goto case_register; 2577 } 2578 base = Para.size - BPoff; // cancel out add of BPoff 2579 goto L1; 2580 2581 case SCauto: 2582 if (s.Sfl == FLreg) 2583 goto case_register; 2584 case_auto: 2585 base = Auto.size; 2586 L1: 2587 if (s.Sscope) // local variables moved into the closure cannot be emitted directly 2588 goto Lret; 2589 TOWORD(debsym + 2,I32 ? S_BPREL32 : S_BPREL16); 2590 if (config.fulltypes == CV4) 2591 { TOOFFSET(debsym + 4,s.Soffset + base + BPoff); 2592 TOIDX(debsym + 4 + _tysize[TYint],typidx); 2593 } 2594 else 2595 { TOOFFSET(debsym + 4 + cgcv.sz_idx,s.Soffset + base + BPoff); 2596 TOIDX(debsym + 4,typidx); 2597 } 2598 length = 2 + 2 + _tysize[TYint] + cgcv.sz_idx; 2599 length += cv_namestring(debsym + length,id); 2600 TOWORD(debsym,length - 2); 2601 break; 2602 2603 case SCbprel: 2604 base = -BPoff; 2605 goto L1; 2606 2607 case SCfastpar: 2608 if (s.Sfl != FLreg) 2609 { base = Fast.size; 2610 goto L1; 2611 } 2612 goto case_register; 2613 2614 case SCregister: 2615 if (s.Sfl != FLreg) 2616 goto case_auto; 2617 goto case_register; 2618 2619 case SCpseudo: 2620 case_register: 2621 TOWORD(debsym + 2,S_REGISTER); 2622 reg = cv_regnum(s); 2623 TOIDX(debsym + 4,typidx); 2624 TOWORD(debsym + 4 + cgcv.sz_idx,reg); 2625 length = 2 * 3 + cgcv.sz_idx; 2626 length += 1 + cv_namestring(debsym + length,id); 2627 TOWORD(debsym,length - 2); 2628 break; 2629 2630 case SCextern: 2631 case SCcomdef: 2632 // Common blocks have a non-zero Sxtrnnum and an UNKNOWN seg 2633 if (!(s.Sxtrnnum && s.Sseg == UNKNOWN)) // if it's not really a common block 2634 { 2635 goto Lret; 2636 } 2637 goto case; 2638 case SCglobal: 2639 case SCcomdat: 2640 u = S_GDATA16; 2641 goto L2; 2642 2643 case SCstatic: 2644 case SClocstat: 2645 u = S_LDATA16; 2646 L2: 2647 if (I32) 2648 u += S_GDATA32 - S_GDATA16; 2649 TOWORD(debsym + 2,u); 2650 if (config.fulltypes == CV4) 2651 { 2652 fixoff = 4; 2653 length = 2 + 2 + _tysize[TYint] + 2; 2654 TOOFFSET(debsym + fixoff,s.Soffset); 2655 TOWORD(debsym + fixoff + _tysize[TYint],0); 2656 TOIDX(debsym + length,typidx); 2657 } 2658 else 2659 { 2660 fixoff = 8; 2661 length = 2 + 2 + _tysize[TYint] + 2; 2662 TOOFFSET(debsym + fixoff,s.Soffset); 2663 TOWORD(debsym + fixoff + _tysize[TYint],0); // segment 2664 TOIDX(debsym + 4,typidx); 2665 } 2666 length += cgcv.sz_idx; 2667 length += cv_namestring(debsym + length,id); 2668 TOWORD(debsym,length - 2); 2669 assert(length <= 40 + len); 2670 2671 if (s.Sseg == UNKNOWN || s.Sclass == SCcomdat) // if common block 2672 { 2673 if (config.exe & EX_flat) 2674 { 2675 fd = 0x16; 2676 idx1 = DGROUPIDX; 2677 idx2 = s.Sxtrnnum; 2678 } 2679 else 2680 { 2681 fd = 0x26; 2682 idx1 = idx2 = s.Sxtrnnum; 2683 } 2684 } 2685 else if (s.ty() & (mTYfar | mTYcs)) 2686 { 2687 fd = 0x04; 2688 idx1 = idx2 = SegData[s.Sseg].segidx; 2689 } 2690 else 2691 { fd = 0x14; 2692 idx1 = DGROUPIDX; 2693 idx2 = SegData[s.Sseg].segidx; 2694 } 2695 /* Because of the linker limitations, the length cannot 2696 * exceed 0x1000. 2697 * See optlink\cv\cvhashes.asm 2698 */ 2699 assert(length <= 0x1000); 2700 if (idx2 != 0) 2701 { uint offset = cast(uint)Offset(DEBSYM); 2702 objmod.write_bytes(SegData[DEBSYM],length,debsym); 2703 objmod.write_long(DEBSYM,offset + fixoff,cast(uint)s.Soffset, 2704 cgcv.LCFDpointer + fd,idx1,idx2); 2705 } 2706 goto Lret; 2707 2708 static if (1) 2709 { 2710 case SCtypedef: 2711 s.Stypidx = typidx; 2712 reset_symbuf.write((&s)[0 .. 1]); 2713 goto L4; 2714 2715 case SCstruct: 2716 if (s.Sstruct.Sflags & STRnotagname) 2717 goto Lret; 2718 goto L4; 2719 2720 case SCenum: 2721 version (SCPP) 2722 { 2723 if (CPP && s.Senum.SEflags & SENnotagname) 2724 goto Lret; 2725 } 2726 L4: 2727 // Output a 'user-defined type' for the tag name 2728 TOWORD(debsym + 2,S_UDT); 2729 TOIDX(debsym + 4,typidx); 2730 length = 2 + 2 + cgcv.sz_idx; 2731 length += cv_namestring(debsym + length,id); 2732 TOWORD(debsym,length - 2); 2733 list_subtract(&cgcv.list,s); 2734 break; 2735 2736 case SCconst: 2737 // The only constants are enum members 2738 value = cast(uint)el_tolongt(s.Svalue); 2739 TOWORD(debsym + 2,S_CONST); 2740 TOIDX(debsym + 4,typidx); 2741 length = 4 + cgcv.sz_idx; 2742 cv4_storenumeric(debsym + length,value); 2743 length += cv4_numericbytes(value); 2744 length += cv_namestring(debsym + length,id); 2745 TOWORD(debsym,length - 2); 2746 break; 2747 } 2748 default: 2749 goto Lret; 2750 } 2751 assert(length <= 40 + len); 2752 objmod.write_bytes(SegData[DEBSYM],length,debsym); 2753 } 2754 Lret: 2755 if (debsym != buf.ptr) 2756 free(debsym); 2757 } 2758 2759 /****************************************** 2760 * Write out any deferred symbols. 2761 */ 2762 2763 private void cv_outlist() 2764 { 2765 while (cgcv.list) 2766 cv_outsym(cast(Symbol *) list_pop(&cgcv.list)); 2767 } 2768 2769 /****************************************** 2770 * Write out symbol table for current function. 2771 */ 2772 2773 private void cv4_func(Funcsym *s, ref symtab_t symtab) 2774 { 2775 int endarg; 2776 2777 cv4_outsym(s); // put out function symbol 2778 version (MARS) 2779 { 2780 __gshared Funcsym* sfunc; 2781 __gshared int cntOpenBlocks; 2782 sfunc = s; 2783 cntOpenBlocks = 0; 2784 2785 struct cv4 2786 { 2787 nothrow: 2788 // record for CV record S_BLOCK32 2789 struct block32_data 2790 { 2791 ushort len; 2792 ushort id; 2793 uint pParent; 2794 uint pEnd; 2795 uint length; 2796 uint offset; 2797 ushort seg; 2798 ubyte[2] name; 2799 } 2800 2801 extern (C++): 2802 2803 static void endArgs() 2804 { 2805 __gshared ushort[2] endargs = [ 2, S_ENDARG ]; 2806 objmod.write_bytes(SegData[DEBSYM],(endargs).sizeof,endargs.ptr); 2807 } 2808 static void beginBlock(int offset, int length) 2809 { 2810 if (++cntOpenBlocks >= 255) 2811 return; // optlink does not like more than 255 scope blocks 2812 2813 uint soffset = cast(uint)Offset(DEBSYM); 2814 // parent and end to be filled by linker 2815 block32_data block32 = { (block32_data).sizeof - 2, S_BLOCK32, 0, 0, length, 0, 0, [ 0, '\0' ] }; 2816 objmod.write_bytes(SegData[DEBSYM], (block32).sizeof, &block32); 2817 size_t offOffset = cast(char*)&block32.offset - cast(char*)&block32; 2818 objmod.reftoident(DEBSYM, soffset + offOffset, sfunc, offset + sfunc.Soffset, CFseg | CFoff); 2819 } 2820 static void endBlock() 2821 { 2822 if (cntOpenBlocks-- >= 255) 2823 return; // optlink does not like more than 255 scope blocks 2824 2825 __gshared ushort[2] endargs = [ 2, S_END ]; 2826 objmod.write_bytes(SegData[DEBSYM],(endargs).sizeof,endargs.ptr); 2827 } 2828 } 2829 2830 varStats_writeSymbolTable(symtab, &cv4_outsym, &cv4.endArgs, &cv4.beginBlock, &cv4.endBlock); 2831 } 2832 else 2833 { 2834 // Put out local symbols 2835 endarg = 0; 2836 foreach (sa; symtab[]) 2837 { //printf("symtab[%d] = %p\n",si,symtab[si]); 2838 cv4_outsym(sa); 2839 } 2840 } 2841 2842 // Put out function return record 2843 if (1) 2844 { ubyte[2+2+2+1+1+4] sreturn = void; 2845 ushort flags; 2846 ubyte style; 2847 tym_t ty; 2848 tym_t tyret; 2849 uint u; 2850 2851 u = 2+2+1; 2852 ty = tybasic(s.ty()); 2853 2854 flags = tyrevfunc(ty) ? 0 : 1; 2855 flags |= typfunc(ty) ? 0 : 2; 2856 TOWORD(sreturn.ptr + 4,flags); 2857 2858 tyret = tybasic(s.Stype.Tnext.Tty); 2859 switch (tyret) 2860 { 2861 case TYvoid: 2862 default: 2863 style = 0; 2864 break; 2865 2866 case TYbool: 2867 case TYchar: 2868 case TYschar: 2869 case TYuchar: 2870 sreturn[7] = 1; 2871 sreturn[8] = 1; // AL 2872 goto L1; 2873 2874 case TYwchar_t: 2875 case TYchar16: 2876 case TYshort: 2877 case TYushort: 2878 goto case_ax; 2879 2880 case TYint: 2881 case TYuint: 2882 case TYsptr: 2883 case TYcptr: 2884 case TYnullptr: 2885 case TYnptr: 2886 case TYnref: 2887 if (I32) 2888 goto case_eax; 2889 else 2890 goto case_ax; 2891 2892 case TYfloat: 2893 case TYifloat: 2894 if (config.exe & EX_flat) 2895 goto case_st0; 2896 goto case; 2897 2898 case TYlong: 2899 case TYulong: 2900 case TYdchar: 2901 if (I32) 2902 goto case_eax; 2903 else 2904 goto case_dxax; 2905 2906 case TYfptr: 2907 case TYhptr: 2908 if (I32) 2909 goto case_edxeax; 2910 else 2911 goto case_dxax; 2912 2913 case TYvptr: 2914 if (I32) 2915 goto case_edxebx; 2916 else 2917 goto case_dxbx; 2918 2919 case TYdouble: 2920 case TYidouble: 2921 case TYdouble_alias: 2922 if (config.exe & EX_flat) 2923 goto case_st0; 2924 if (I32) 2925 goto case_edxeax; 2926 else 2927 goto case_axbxcxdx; 2928 2929 case TYllong: 2930 case TYullong: 2931 assert(I32); 2932 goto case_edxeax; 2933 2934 case TYldouble: 2935 case TYildouble: 2936 goto case_st0; 2937 2938 case TYcfloat: 2939 case TYcdouble: 2940 case TYcldouble: 2941 goto case_st01; 2942 2943 case_ax: 2944 sreturn[7] = 1; 2945 sreturn[8] = 9; // AX 2946 goto L1; 2947 2948 case_eax: 2949 sreturn[7] = 1; 2950 sreturn[8] = 17; // EAX 2951 goto L1; 2952 2953 2954 case_dxax: 2955 sreturn[7] = 2; 2956 sreturn[8] = 11; // DX 2957 sreturn[9] = 9; // AX 2958 goto L1; 2959 2960 case_dxbx: 2961 sreturn[7] = 2; 2962 sreturn[8] = 11; // DX 2963 sreturn[9] = 12; // BX 2964 goto L1; 2965 2966 case_axbxcxdx: 2967 sreturn[7] = 4; 2968 sreturn[8] = 9; // AX 2969 sreturn[9] = 12; // BX 2970 sreturn[10] = 10; // CX 2971 sreturn[11] = 11; // DX 2972 goto L1; 2973 2974 case_edxeax: 2975 sreturn[7] = 2; 2976 sreturn[8] = 19; // EDX 2977 sreturn[9] = 17; // EAX 2978 goto L1; 2979 2980 case_edxebx: 2981 sreturn[7] = 2; 2982 sreturn[8] = 19; // EDX 2983 sreturn[9] = 20; // EBX 2984 goto L1; 2985 2986 case_st0: 2987 sreturn[7] = 1; 2988 sreturn[8] = 128; // ST0 2989 goto L1; 2990 2991 case_st01: 2992 sreturn[7] = 2; 2993 sreturn[8] = 128; // ST0 (imaginary) 2994 sreturn[9] = 129; // ST1 (real) 2995 goto L1; 2996 2997 L1: 2998 style = 1; 2999 u += sreturn[7] + 1; 3000 break; 3001 } 3002 sreturn[6] = style; 3003 3004 TOWORD(sreturn.ptr,u); 3005 TOWORD(sreturn.ptr + 2,S_RETURN); 3006 objmod.write_bytes(SegData[DEBSYM],u + 2,sreturn.ptr); 3007 } 3008 3009 // Put out end scope 3010 { __gshared ushort[2] endproc = [ 2,S_END ]; 3011 3012 objmod.write_bytes(SegData[DEBSYM],(endproc).sizeof,endproc.ptr); 3013 } 3014 3015 cv_outlist(); 3016 } 3017 3018 ////////////////////////////////////////////////////////// 3019 3020 /****************************************** 3021 * Write out data to .OBJ file. 3022 */ 3023 3024 void cv_term() 3025 { 3026 //printf("cv_term(): debtyp.length = %d\n",debtyp.length); 3027 3028 segidx_t typeseg = objmod.seg_debugT(); 3029 3030 switch (config.fulltypes) 3031 { 3032 case CV4: 3033 case CVSYM: 3034 cv_outlist(); 3035 goto case; 3036 case CV8: 3037 objmod.write_bytes(SegData[typeseg],4,&cgcv.signature); 3038 if (debtyp.length != 1 || config.fulltypes == CV8) 3039 { 3040 for (uint u = 0; u < debtyp.length; u++) 3041 { debtyp_t *d = debtyp[u]; 3042 3043 objmod.write_bytes(SegData[typeseg],2 + d.length,cast(char *)d + uint.sizeof); 3044 debtyp_free(d); 3045 } 3046 } 3047 else if (debtyp.length) 3048 { 3049 debtyp_free(debtyp[0]); 3050 } 3051 break; 3052 3053 static if (SYMDEB_TDB) 3054 { 3055 case CVTDB: 3056 cv_outlist(); 3057 static if (1) 3058 { 3059 tdb_term(); 3060 } 3061 else 3062 { 3063 { ubyte *buf; 3064 ubyte *p; 3065 size_t len; 3066 3067 // Calculate size of buffer 3068 len = 4; 3069 for (uint u = 0; u < debtyp.length; u++) 3070 { debtyp_t *d = debtyp[u]; 3071 3072 len += 2 + d.length; 3073 } 3074 3075 // Allocate buffer 3076 buf = malloc(len); 3077 if (!buf) 3078 err_nomem(); // out of memory 3079 3080 // Fill the buffer 3081 TOLONG(buf,cgcv.signature); 3082 p = buf + 4; 3083 for (uint u = 0; u < debtyp.length; u++) 3084 { debtyp_t *d = debtyp[u]; 3085 3086 len = 2 + d.length; 3087 memcpy(p,cast(char *)d + uint.sizeof,len); 3088 p += len; 3089 } 3090 3091 tdb_write(buf,len,debtyp.length); 3092 } 3093 } 3094 break; 3095 } 3096 3097 default: 3098 assert(0); 3099 } 3100 3101 // debtyp.dtor(); // save for later 3102 vec_free(debtypvec); 3103 debtypvec = null; 3104 } 3105 3106 /****************************************** 3107 * Write out symbol table for current function. 3108 */ 3109 3110 void cv_func(Funcsym *s) 3111 { 3112 version (SCPP) 3113 { 3114 if (errcnt) // if we had any errors 3115 return; // don't bother putting stuff in .OBJ file 3116 } 3117 3118 //printf("cv_func('%s')\n",s.Sident.ptr); 3119 version (MARS) 3120 { 3121 if (s.Sflags & SFLnodebug) 3122 return; 3123 } 3124 else 3125 { 3126 if (CPP && s.Sfunc.Fflags & Fnodebug) // if don't generate debug info 3127 return; 3128 } 3129 switch (config.fulltypes) 3130 { 3131 case CV4: 3132 case CVSYM: 3133 case CVTDB: 3134 cv4_func(s, globsym); 3135 break; 3136 3137 default: 3138 assert(0); 3139 } 3140 } 3141 3142 /****************************************** 3143 * Write out symbol table for current function. 3144 */ 3145 3146 void cv_outsym(Symbol *s) 3147 { 3148 //printf("cv_outsym('%s')\n",s.Sident.ptr); 3149 symbol_debug(s); 3150 version (MARS) 3151 { 3152 if (s.Sflags & SFLnodebug) 3153 return; 3154 } 3155 switch (config.fulltypes) 3156 { 3157 case CV4: 3158 case CVSYM: 3159 case CVTDB: 3160 cv4_outsym(s); 3161 break; 3162 3163 version (MARS) 3164 { 3165 case CV8: 3166 cv8_outsym(s); 3167 break; 3168 } 3169 3170 default: 3171 assert(0); 3172 } 3173 } 3174 3175 /****************************************** 3176 * Return cv type index for a type. 3177 */ 3178 3179 uint cv_typidx(type *t) 3180 { uint ti; 3181 3182 //printf("cv_typidx(%p)\n",t); 3183 switch (config.fulltypes) 3184 { 3185 case CV4: 3186 case CVTDB: 3187 case CVSYM: 3188 case CV8: 3189 ti = cv4_typidx(t); 3190 break; 3191 3192 default: 3193 debug 3194 printf("fulltypes = %d\n",config.fulltypes); 3195 3196 assert(0); 3197 } 3198 return ti; 3199 } 3200 3201 }