1: 
  2: // Copyright (c) 2004-2011 by Digital Mars
  3: // All Rights Reserved
  4: // written by Walter Bright
  5: // http://www.digitalmars.com
  6: 
  7: #include <stdio.h>
  8: #include <stddef.h>
  9: #include <time.h>
 10: 
 11: #include "mars.h"
 12: #include "module.h"
 13: #include "mtype.h"
 14: #include "declaration.h"
 15: #include "statement.h"
 16: #include "enum.h"
 17: #include "aggregate.h"
 18: #include "init.h"
 19: #include "attrib.h"
 20: #include "id.h"
 21: #include "import.h"
 22: #include "template.h"
 23: 
 24: #include "rmem.h"
 25: #include "cc.h"
 26: #include "global.h"
 27: #include "oper.h"
 28: #include "code.h"
 29: #include "type.h"
 30: #include "dt.h"
 31: #include "cv4.h"
 32: #include "cgcv.h"
 33: #include "outbuf.h"
 34: #include "irstate.h"
 35: 
 36: static char __file__[] = __FILE__;      /* for tassert.h                */
 37: #include        "tassert.h"
 38: 
 39: /* The CV4 debug format is defined in:
 40:  *      "CV4 Symbolic Debug Information Specification"
 41:  *      rev 3.1 March 5, 1993
 42:  *      Languages Business Unit
 43:  *      Microsoft
 44:  */
 45: 
 46: /******************************
 47:  * CV4 pg. 25
 48:  * Convert D protection attribute to cv attribute.
 49:  */
 50: 
 51: unsigned PROTtoATTR(enum PROT prot)
 52: {
 53:     unsigned attribute;
 54: 
 55:     switch (prot)
 56:     {
 57:         case PROTprivate:       attribute = 1;  break;
 58:         case PROTpackage:       attribute = 2;  break;
 59:         case PROTprotected:     attribute = 2;  break;
 60:         case PROTpublic:        attribute = 3;  break;
 61:         case PROTexport:        attribute = 3;  break;
 62: 
 63:         case PROTundefined:
 64:         case PROTnone:
 65:         default:
 66:             //printf("prot = %d\n", prot);
 67:             assert(0);
 68:     }
 69:     return attribute;
 70: }
 71: 
 72: unsigned cv4_memfunctypidx(FuncDeclaration *fd)
 73: {   type *t;
 74:     debtyp_t *d;
 75:     unsigned char *p;
 76:     AggregateDeclaration *ad;
 77: 
 78:     //printf("cv4_memfunctypidx(fd = '%s')\n", fd->toChars());
 79:     t = fd->type->toCtype();
 80:     ad = fd->isMember2();
 81:     if (ad)
 82:     {
 83:         unsigned nparam;
 84:         idx_t paramidx;
 85:         idx_t thisidx;
 86:         unsigned u;
warning C4101: 'u' : unreferenced local variable
87: unsigned char call; 88: 89: // It's a member function, which gets a special type record 90: 91: if (fd->isStatic()) 92: thisidx = dttab4[TYvoid]; 93: else 94: { 95: assert(ad->handle); 96: thisidx = cv4_typidx(ad->handle->toCtype()); 97: } 98: 99: paramidx = cv4_arglist(t,&nparam); 100: call = cv4_callconv(t); 101: 102: d = debtyp_alloc(18); 103: p = d->data; 104: TOWORD(p,LF_MFUNCTION); 105: TOWORD(p + 2,cv4_typidx(t->Tnext)); 106: TOWORD(p + 4,cv4_typidx(ad->type->toCtype())); 107: TOWORD(p + 6,thisidx); 108: p[8] = call; 109: p[9] = 0; // reserved 110: TOWORD(p + 10,nparam); 111: TOWORD(p + 12,paramidx); 112: TOLONG(p + 14,0); // thisadjust 113: 114: return cv_debtyp(d); 115: } 116: return cv4_typidx(t); 117: } 118: 119: unsigned cv4_Denum(EnumDeclaration *e) 120: { 121: debtyp_t *d,*dt; 122: unsigned nfields,fnamelen; 123: unsigned len; 124: unsigned property; 125: unsigned attribute; 126: int i; 127: const char *id; 128: idx_t typidx; 129: 130: //dbg_printf("cv4_Denum(%s)\n", e->toChars()); 131: property = 0; 132: if (!e->members || !e->memtype) 133: property |= 0x80; // enum is forward referenced 134: 135: id = e->toPrettyChars(); 136: len = 10; 137: d = debtyp_alloc(len + cv_stringbytes(id)); 138: TOWORD(d->data,LF_ENUM); 139: TOWORD(d->data + 4,e->memtype ? cv4_typidx(e->memtype->toCtype()) : 0); 140: TOWORD(d->data + 8,property); 141: len += cv_namestring(d->data + len,id); 142: 143: d->length = 0; // so cv_debtyp() will allocate new 144: typidx = cv_debtyp(d); 145: d->length = len; // restore length 146: 147: // Compute the number of fields, and the length of the fieldlist record 148: nfields = 0; 149: fnamelen = 2; 150: if (!property) 151: { 152: for (i = 0; i < e->members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
153: { EnumMember *sf = (e->members->tdata()[i])->isEnumMember(); 154: dinteger_t value; 155: 156: if (sf) 157: { 158: value = sf->value->toInteger(); 159: unsigned fnamelen1 = fnamelen; 160: // store only member's simple name 161: fnamelen += 4 + cv4_numericbytes(value) + cv_stringbytes(sf->toChars());
warning C4244: 'argument' : conversion from 'dinteger_t' to 'targ_size_t', possible loss of data
162: 163: /* Optlink dies on longer ones, so just truncate 164: */ 165: if (fnamelen > 0xB000) // 0xB000 found by trial and error 166: { fnamelen = fnamelen1; // back up 167: break; // and skip the rest 168: } 169: 170: nfields++; 171: } 172: } 173: } 174: 175: TOWORD(d->data + 2,nfields); 176: 177: // If forward reference, then field list is 0 178: if (property) 179: { 180: TOWORD(d->data + 6,0); 181: return typidx; 182: } 183: 184: // Generate fieldlist type record 185: dt = debtyp_alloc(fnamelen); 186: TOWORD(dt->data,LF_FIELDLIST); 187: 188: // And fill it in 189: int j = 2; 190: int fieldi = 0; 191: for (i = 0; i < e->members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
192: { EnumMember *sf = (e->members->tdata()[i])->isEnumMember(); 193: dinteger_t value; 194: 195: if (sf) 196: { 197: fieldi++; 198: if (fieldi > nfields)
warning C4018: '>' : signed/unsigned mismatch
199: break; // chop off the rest 200: 201: value = sf->value->toInteger(); 202: TOWORD(dt->data + j,LF_ENUMERATE); 203: attribute = 0; 204: TOWORD(dt->data + j + 2,attribute); 205: cv4_storenumeric(dt->data + j + 4,value);
warning C4244: 'argument' : conversion from 'dinteger_t' to 'targ_size_t', possible loss of data
206: j += 4 + cv4_numericbytes(value);
warning C4244: 'argument' : conversion from 'dinteger_t' to 'targ_size_t', possible loss of data
207: // store only member's simple name 208: j += cv_namestring(dt->data + j, sf->toChars()); 209: 210: // If enum is not a member of a class, output enum members as constants 211: // if (!isclassmember(s)) 212: // { 213: // cv4_outsym(sf); 214: // } 215: } 216: } 217: assert(j == fnamelen); 218: TOWORD(d->data + 6,cv_debtyp(dt)); 219: 220: // cv4_outsym(s); 221: return typidx; 222: } 223: 224: /* ==================================================================== */ 225: 226: /**************************** 227: * Emit symbolic debug info in CV format. 228: */ 229: 230: void TypedefDeclaration::toDebug() 231: { 232: //printf("TypedefDeclaration::toDebug('%s')\n", toChars()); 233: 234: assert(config.fulltypes >= CV4); 235: 236: // If it is a member, it is handled by cvMember() 237: if (!isMember()) 238: { 239: if (basetype->ty == Ttuple) 240: return; 241: 242: unsigned length; 243: const char *id = toPrettyChars(); 244: idx_t typidx = cv4_typidx(basetype->toCtype()); 245: unsigned len = strlen(id); 246: unsigned char *debsym = (unsigned char *) alloca(39 + IDOHD + len);
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
247: 248: // Output a 'user-defined type' for the tag name 249: TOWORD(debsym + 2,S_UDT); 250: TOIDX(debsym + 4,typidx); 251: length = 2 + 2 + cgcv.sz_idx; 252: length += cv_namestring(debsym + length,id); 253: TOWORD(debsym,length - 2); 254: 255: assert(length <= 40 + len); 256: obj_write_bytes(SegData[DEBSYM],length,debsym); 257: } 258: } 259: 260: 261: void EnumDeclaration::toDebug() 262: { 263: //printf("EnumDeclaration::toDebug('%s')\n", toChars()); 264: 265: assert(config.fulltypes >= CV4); 266: 267: // If it is a member, it is handled by cvMember() 268: if (!isMember()) 269: { 270: unsigned length; 271: const char *id = toPrettyChars(); 272: idx_t typidx = cv4_Denum(this); 273: unsigned len = strlen(id); 274: unsigned char *debsym = (unsigned char *) alloca(39 + IDOHD + len);
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
275: 276: // Output a 'user-defined type' for the tag name 277: TOWORD(debsym + 2,S_UDT); 278: TOIDX(debsym + 4,typidx); 279: length = 2 + 2 + cgcv.sz_idx; 280: length += cv_namestring(debsym + length,id); 281: TOWORD(debsym,length - 2); 282: 283: assert(length <= 40 + len); 284: obj_write_bytes(SegData[DEBSYM],length,debsym); 285: } 286: } 287: 288: 289: void StructDeclaration::toDebug() 290: { 291: unsigned leaf; 292: unsigned property; 293: unsigned nfields; 294: unsigned fnamelen; 295: const char *id; 296: targ_size_t size; 297: unsigned numidx; 298: debtyp_t *d,*dt; 299: unsigned len; 300: int i; 301: int count; // COUNT field in LF_CLASS 302: unsigned char *p; 303: idx_t typidx = 0; 304: 305: //printf("StructDeclaration::toDebug('%s')\n", toChars()); 306: 307: assert(config.fulltypes >= CV4); 308: if (isAnonymous()) 309: return /*0*/; 310: 311: if (typidx) // if reference already generated 312: return /*typidx*/; // use already existing reference 313: 314: property = 0; 315: if (!members) 316: { size = 0; 317: property |= 0x80; // forward reference 318: } 319: else 320: size = structsize; 321: 322: if (parent->isAggregateDeclaration()) // if class is nested 323: property |= 8; 324: // if (st->Sctor || st->Sdtor) 325: // property |= 2; // class has ctors and/or dtors 326: // if (st->Sopoverload) 327: // property |= 4; // class has overloaded operators 328: // if (st->Scastoverload) 329: // property |= 0x40; // class has casting methods 330: // if (st->Sopeq && !(st->Sopeq->Sfunc->Fflags & Fnodebug)) 331: // property |= 0x20; // class has overloaded assignment 332: 333: id = toPrettyChars(); 334: numidx = isUnionDeclaration() ? 8 : 12; 335: len = numidx + cv4_numericbytes(size); 336: d = debtyp_alloc(len + cv_stringbytes(id)); 337: cv4_storenumeric(d->data + numidx,size); 338: len += cv_namestring(d->data + len,id); 339: 340: leaf = isUnionDeclaration() ? LF_UNION : LF_STRUCTURE; 341: if (!isUnionDeclaration()) 342: { 343: TOWORD(d->data + 8,0); // dList 344: TOWORD(d->data + 10,0); // vshape is 0 (no virtual functions) 345: } 346: TOWORD(d->data,leaf); 347: 348: // Assign a number to prevent infinite recursion if a struct member 349: // references the same struct. 350: d->length = 0; // so cv_debtyp() will allocate new 351: typidx = cv_debtyp(d); 352: d->length = len; // restore length 353: 354: if (!members) // if reference only 355: { 356: TOWORD(d->data + 2,0); // count: number of fields is 0 357: TOWORD(d->data + 4,0); // field list is 0 358: TOWORD(d->data + 6,property); 359: return /*typidx*/; 360: } 361: 362: // Compute the number of fields, and the length of the fieldlist record 363: nfields = 0; 364: fnamelen = 2; 365: 366: count = nfields; 367: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
368: { Dsymbol *s = members->tdata()[i]; 369: int nwritten; 370: 371: nwritten = s->cvMember(NULL); 372: if (nwritten) 373: { 374: fnamelen += nwritten; 375: nfields++; 376: count++; 377: } 378: } 379: 380: TOWORD(d->data + 2,count); 381: TOWORD(d->data + 6,property); 382: 383: // Generate fieldlist type record 384: dt = debtyp_alloc(fnamelen); 385: p = dt->data; 386: 387: // And fill it in 388: TOWORD(p,LF_FIELDLIST); 389: p += 2; 390: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
391: { Dsymbol *s = members->tdata()[i]; 392: 393: p += s->cvMember(p); 394: } 395: 396: //dbg_printf("fnamelen = %d, p-dt->data = %d\n",fnamelen,p-dt->data); 397: assert(p - dt->data == fnamelen); 398: TOWORD(d->data + 4,cv_debtyp(dt)); 399: 400: // cv4_outsym(s); 401: 402: unsigned char *debsym; 403: unsigned length; 404: 405: len = strlen(id); 406: debsym = (unsigned char *) alloca(39 + IDOHD + len);
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
407: 408: // Output a 'user-defined type' for the tag name 409: TOWORD(debsym + 2,S_UDT); 410: TOIDX(debsym + 4,typidx); 411: length = 2 + 2 + cgcv.sz_idx; 412: length += cv_namestring(debsym + length,id); 413: TOWORD(debsym,length - 2); 414: 415: assert(length <= 40 + len); 416: obj_write_bytes(SegData[DEBSYM],length,debsym); 417: 418: // return typidx; 419: } 420: 421: 422: void ClassDeclaration::toDebug() 423: { 424: unsigned leaf; 425: unsigned property; 426: unsigned nfields; 427: unsigned fnamelen; 428: const char *id; 429: targ_size_t size; 430: unsigned numidx; 431: debtyp_t *d,*dt; 432: unsigned len; 433: int i; 434: int count; // COUNT field in LF_CLASS 435: unsigned char *p; 436: idx_t typidx = 0; 437: 438: //printf("ClassDeclaration::toDebug('%s')\n", toChars()); 439: 440: assert(config.fulltypes >= CV4); 441: if (isAnonymous()) 442: return /*0*/; 443: 444: if (typidx) // if reference already generated 445: return /*typidx*/; // use already existing reference 446: 447: property = 0; 448: if (!members) 449: { size = 0; 450: property |= 0x80; // forward reference 451: } 452: else 453: size = structsize; 454: 455: if (parent->isAggregateDeclaration()) // if class is nested 456: property |= 8; 457: if (ctor || dtors.dim) 458: property |= 2; // class has ctors and/or dtors 459: // if (st->Sopoverload) 460: // property |= 4; // class has overloaded operators 461: // if (st->Scastoverload) 462: // property |= 0x40; // class has casting methods 463: // if (st->Sopeq && !(st->Sopeq->Sfunc->Fflags & Fnodebug)) 464: // property |= 0x20; // class has overloaded assignment 465: 466: id = isCPPinterface() ? ident->toChars() : toPrettyChars(); 467: numidx = isUnionDeclaration() ? 8 : 12; 468: len = numidx + cv4_numericbytes(size); 469: d = debtyp_alloc(len + cv_stringbytes(id)); 470: cv4_storenumeric(d->data + numidx,size); 471: len += cv_namestring(d->data + len,id); 472: 473: leaf = LF_CLASS; 474: TOWORD(d->data + 8,0); // dList 475: 476: if (1) 477: { debtyp_t *vshape; 478: unsigned n; 479: unsigned char descriptor; 480: 481: n = vtbl.dim; // number of virtual functions 482: if (n == 0) 483: { 484: TOWORD(d->data + 10,0); // vshape is 0 485: } 486: else 487: { int i;
warning C6246: Local declaration of 'i' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '433' of 'c:\projects\extern\d\dmd\src\tocvdebug.c': Lines: 433
488: 489: vshape = debtyp_alloc(4 + (n + 1) / 2); 490: TOWORD(vshape->data,LF_VTSHAPE); 491: TOWORD(vshape->data + 2,1); 492: 493: n = 0; 494: descriptor = 0; 495: for (i = 0; i < vtbl.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
496: { FuncDeclaration *fd = (FuncDeclaration *)vtbl.tdata()[i]; 497: tym_t ty;
warning C4101: 'ty' : unreferenced local variable
498: 499: //if (intsize == 4) 500: descriptor |= 5; 501: vshape->data[4 + n / 2] = descriptor;
warning C6386: Buffer overrun: accessing 'vshape->data', the writable size is '2' bytes, but '5' bytes might be written: Lines: 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 440, 441, 444, 447, 448, 453, 455, 456, 457, 458, 466, 467, 468, 469, 470, 471, 473, 474, 476, 477, 478, 479, 481, 482, 487, 489, 490, 491, 493, 494, 495, 496, 497, 500, 501
502: descriptor <<= 4; 503: n++; 504: } 505: TOWORD(d->data + 10,cv_debtyp(vshape)); // vshape 506: } 507: } 508: else 509: TOWORD(d->data + 10,0); // vshape is 0 (no virtual functions) 510: 511: TOWORD(d->data,leaf); 512: 513: // Assign a number to prevent infinite recursion if a struct member 514: // references the same struct. 515: d->length = 0; // so cv_debtyp() will allocate new 516: typidx = cv_debtyp(d); 517: d->length = len; // restore length 518: 519: if (!members) // if reference only 520: { 521: TOWORD(d->data + 2,0); // count: number of fields is 0 522: TOWORD(d->data + 4,0); // field list is 0 523: TOWORD(d->data + 6,property); 524: return /*typidx*/; 525: } 526: 527: // Compute the number of fields, and the length of the fieldlist record 528: nfields = 0; 529: fnamelen = 2; 530: 531: // Add in base classes 532: for (i = 0; i < baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
533: { BaseClass *bc = baseclasses->tdata()[i]; 534: 535: nfields++; 536: fnamelen += 6 + cv4_numericbytes(bc->offset); 537: } 538: 539: count = nfields; 540: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
541: { Dsymbol *s = members->tdata()[i]; 542: int nwritten; 543: 544: nwritten = s->cvMember(NULL); 545: if (nwritten) 546: { 547: fnamelen += nwritten; 548: nfields++; 549: count++; 550: } 551: } 552: 553: TOWORD(d->data + 2,count); 554: TOWORD(d->data + 6,property); 555: 556: // Generate fieldlist type record 557: dt = debtyp_alloc(fnamelen); 558: p = dt->data; 559: 560: // And fill it in 561: TOWORD(p,LF_FIELDLIST); 562: p += 2; 563: 564: // Add in base classes 565: for (i = 0; i < baseclasses->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
566: { BaseClass *bc = baseclasses->tdata()[i]; 567: idx_t typidx;
warning C6246: Local declaration of 'typidx' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '436' of 'c:\projects\extern\d\dmd\src\tocvdebug.c': Lines: 436
568: unsigned attribute; 569: 570: typidx = cv4_typidx(bc->base->type->toCtype()->Tnext); 571: 572: attribute = PROTtoATTR(bc->protection); 573: 574: TOWORD(p,LF_BCLASS); 575: TOWORD(p + 2,typidx); 576: TOWORD(p + 4,attribute); 577: p += 6; 578: 579: cv4_storenumeric(p, bc->offset); 580: p += cv4_numericbytes(bc->offset); 581: } 582: 583: 584: 585: for (i = 0; i < members->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
586: { Dsymbol *s = members->tdata()[i]; 587: 588: p += s->cvMember(p); 589: } 590: 591: //dbg_printf("fnamelen = %d, p-dt->data = %d\n",fnamelen,p-dt->data); 592: assert(p - dt->data == fnamelen); 593: TOWORD(d->data + 4,cv_debtyp(dt)); 594: 595: // cv4_outsym(s); 596: 597: unsigned char *debsym; 598: unsigned length; 599: 600: len = strlen(id); 601: debsym = (unsigned char *) alloca(39 + IDOHD + len);
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
602: 603: // Output a 'user-defined type' for the tag name 604: TOWORD(debsym + 2,S_UDT); 605: TOIDX(debsym + 4,typidx); 606: length = 2 + 2 + cgcv.sz_idx; 607: length += cv_namestring(debsym + length,id); 608: TOWORD(debsym,length - 2); 609: 610: assert(length <= 40 + len); 611: obj_write_bytes(SegData[DEBSYM],length,debsym); 612: 613: // return typidx; 614: } 615: 616: 617: /* ===================================================================== */ 618: 619: /***************************************** 620: * Insert CV info into *p. 621: * Returns: 622: * number of bytes written, or that would be written if p==NULL 623: */ 624: 625: int Dsymbol::cvMember(unsigned char *p) 626: { 627: return 0; 628: } 629: 630: 631: int TypedefDeclaration::cvMember(unsigned char *p) 632: { 633: char *id; 634: idx_t typidx; 635: unsigned attribute;
warning C4101: 'attribute' : unreferenced local variable
636: int nwritten = 0; 637: debtyp_t *d;
warning C4101: 'd' : unreferenced local variable
638: 639: //printf("TypedefDeclaration::cvMember() '%s'\n", toChars()); 640: id = toChars(); 641: 642: if (!p) 643: { 644: nwritten = 4 + cv_stringbytes(id); 645: } 646: else 647: { 648: TOWORD(p,LF_NESTTYPE); 649: typidx = cv4_typidx(basetype->toCtype()); 650: TOWORD(p + 2,typidx); 651: nwritten = 4 + cv_namestring(p + 4, id); 652: } 653: return nwritten; 654: } 655: 656: 657: int EnumDeclaration::cvMember(unsigned char *p) 658: { 659: char *id; 660: idx_t typidx; 661: unsigned attribute;
warning C4101: 'attribute' : unreferenced local variable
662: int nwritten = 0; 663: debtyp_t *d;
warning C4101: 'd' : unreferenced local variable
664: 665: //printf("EnumDeclaration::cvMember() '%s'\n", toChars()); 666: id = toChars(); 667: 668: if (!p) 669: { 670: nwritten = 4 + cv_stringbytes(id); 671: } 672: else 673: { 674: TOWORD(p,LF_NESTTYPE); 675: typidx = cv4_Denum(this); 676: TOWORD(p + 2,typidx); 677: nwritten = 4 + cv_namestring(p + 4, id); 678: } 679: return nwritten; 680: } 681: 682: 683: int FuncDeclaration::cvMember(unsigned char *p) 684: { 685: char *id; 686: idx_t typidx; 687: unsigned attribute; 688: int nwritten = 0; 689: debtyp_t *d; 690: 691: //printf("FuncDeclaration::cvMember() '%s'\n", toChars()); 692: 693: if (!type) // if not compiled in, 694: return 0; // skip it 695: 696: id = toChars(); 697: 698: if (!p) 699: { 700: nwritten = 6 + cv_stringbytes(id); 701: } 702: else 703: { 704: int count; 705: int mlen; 706: unsigned char *q; 707: 708: count = 0; 709: mlen = 2; 710: { 711: if (introducing) 712: mlen += 4; 713: mlen += cgcv.sz_idx * 2; 714: count++; 715: } 716: 717: // Allocate and fill it in 718: d = debtyp_alloc(mlen); 719: q = d->data; 720: TOWORD(q,LF_METHODLIST); 721: q += 2; 722: // for (s = sf; s; s = s->Sfunc->Foversym) 723: { 724: attribute = PROTtoATTR(prot()); 725: 726: /* 0*4 vanilla method 727: * 1*4 virtual method 728: * 2*4 static method 729: * 3*4 friend method 730: * 4*4 introducing virtual method 731: * 5*4 pure virtual method 732: * 6*4 pure introducing virtual method 733: * 7*4 reserved 734: */ 735: 736: if (isStatic()) 737: attribute |= 2*4; 738: else if (isVirtual()) 739: { 740: if (introducing) 741: { 742: if (isAbstract()) 743: attribute |= 6*4; 744: else 745: attribute |= 4*4; 746: } 747: else 748: { 749: if (isAbstract()) 750: attribute |= 5*4; 751: else 752: attribute |= 1*4; 753: } 754: } 755: else 756: attribute |= 0*4; 757: 758: TOIDX(q,attribute); 759: q += cgcv.sz_idx; 760: TOIDX(q, cv4_memfunctypidx(this)); 761: q += cgcv.sz_idx; 762: if (introducing) 763: { TOLONG(q, vtblIndex * PTRSIZE); 764: q += 4; 765: } 766: } 767: assert(q - d->data == mlen); 768: 769: typidx = cv_debtyp(d); 770: if (typidx) 771: { 772: TOWORD(p,LF_METHOD); 773: TOWORD(p + 2,count); 774: nwritten = 4; 775: TOIDX(p + nwritten, typidx); 776: nwritten += cgcv.sz_idx; 777: nwritten += cv_namestring(p + nwritten, id); 778: } 779: } 780: return nwritten; 781: } 782: 783: int VarDeclaration::cvMember(unsigned char *p) 784: { 785: char *id; 786: idx_t typidx; 787: unsigned attribute; 788: int nwritten = 0; 789: 790: //printf("VarDeclaration::cvMember(p = %p) '%s'\n", p, toChars()); 791: 792: if (type->toBasetype()->ty == Ttuple) 793: return 0; 794: 795: id = toChars(); 796: 797: if (!p) 798: { 799: if (storage_class & STCfield) 800: { 801: nwritten += 6 + 802: cv4_numericbytes(offset) + cv_stringbytes(id); 803: } 804: else if (isStatic()) 805: { 806: nwritten += 6 + cv_stringbytes(id); 807: } 808: } 809: else if (storage_class & STCfield) 810: { 811: TOWORD(p,LF_MEMBER); 812: typidx = cv_typidx(type->toCtype()); 813: attribute = PROTtoATTR(prot()); 814: assert((attribute & ~3) == 0); 815: TOWORD(p + 2,typidx); 816: TOWORD(p + 4,attribute); 817: cv4_storenumeric(p + 6, offset); 818: nwritten = 6 + cv4_numericbytes( offset); 819: nwritten += cv_namestring(p + nwritten, id); 820: } 821: else if (isStatic()) 822: { 823: TOWORD(p,LF_STMEMBER); 824: typidx = cv_typidx(type->toCtype()); 825: attribute = PROTtoATTR(prot()); 826: assert((attribute & ~3) == 0); 827: TOWORD(p + 2,typidx); 828: TOWORD(p + 4,attribute); 829: nwritten = 6 + cv_namestring(p + 6, id); 830: } 831: return nwritten; 832: } 833: 834: