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: