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