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