|
|
1.1 root 1: /*
2: * cc0 - debug table and symbol table type information output.
3: * all intermediate file items are of format:
4: * DLABEL, class, lineno, name, optional value, type.
5: */
6: #ifndef __LINE__
7: #define __LINE__ 0
8: #endif
9: #ifdef vax
10: #include "INC$LIB:cc0.h"
11: #else
12: #include "cc0.h"
13: #endif
14:
15: /*
16: * Called from cc0.c/main() for the original source file name.
17: *
18: * The compiler passes source filename information to the output
19: * writer as DC_FILE debug records. The output writer will
20: * nest file name records, but csd is not prepared to deal with
21: * nested source files so we mark all included source as part
22: * of the line which included it.
23: */
24: dbfname(f)
25: char *f;
26: {
27: if (notvariant(VDEBUG) && notvariant(VLINES))
28: return;
29: bput(DLABEL);
30: bput(DC_FILE);
31: iput((ival_t) line);
32: sput(f);
33: bput(DT_NONE);
34: zput((sizeof_t) 0);
35: }
36:
37: /*
38: * Called from stat.c/statement() at entry, LBRACE, and RBRACE.
39: * Also in cc0.c/xfunc() for declaration brackets.
40: */
41: dbstat(s, line)
42: int s;
43: int line;
44: {
45: register int mys;
46:
47: if (line == 0 || (notvariant(VDEBUG) && notvariant(VLINES))
48: || s==CASE || s==DEFAULT || (s==ID && spnextis(':'))) {
49: return;
50: } else if (s==LBRACE) {
51: mys = '{';
52: } else if (s==RBRACE) {
53: mys = '}';
54: } else {
55: mys = ';';
56: if (notvariant(VLINES))
57: return;
58: }
59: bput(DLABEL);
60: bput(DC_LINE);
61: iput((ival_t) (istackp<istack+NLEV ? istack[NLEV-1].i_line : line));
62: bput(mys);
63: bput(0);
64: bput(DT_NONE);
65: zput((sizeof_t) 0);
66: }
67:
68: /*
69: * Output a label identifier.
70: * These work like line number records in cc2
71: * so that the exact label number assigned is
72: * irrelevant.
73: */
74: dblabel(sp) SYM *sp;
75: {
76: if (notvariant(VDEBUG))
77: return;
78: dbdecl(sp);
79: }
80:
81: /*
82: * Called directly for external and static declaration.
83: * Arg lists are driven by dbargs(),
84: * locals are filtered by dblocal(),
85: * extrefs, typedefs, structs, unions and enums are driven by dblevel().
86: */
87: dbdecl(sp) SYM *sp;
88: {
89: if (notvariant(VDEBUG) && (notvariant(VTYPES) || sp->s_class==C_SEX))
90: return;
91: if (sp->s_seg==SALIEN)
92: return;
93: bput(DLABEL);
94: dbpr(sp);
95: }
96:
97: /*
98: * Put out the parameters to a function.
99: */
100: dbargs()
101: {
102: register int i;
103: register SYM *sp;
104:
105: if (notvariant(VDEBUG))
106: return;
107: for (i = 0; i < nargs; i += 1) {
108: sp = args[i];
109: if (sp->s_class == C_REG) {
110: sp->s_class = C_PREG;
111: dbdecl(sp);
112: sp->s_class = C_REG;
113: } else
114: dbdecl(sp);
115: }
116: }
117:
118: /*
119: * Output a local symbol declaration.
120: * Forget about references.
121: */
122: dblocal(sp) SYM *sp;
123: {
124: register int class;
125:
126: if (notvariant(VDEBUG))
127: return;
128: class = sp->s_class;
129: if (class!=C_GREF
130: && class!=C_GDEF
131: && class!=C_SEX
132: && class!=C_CXT
133: && class!=C_TYPE)
134: dbdecl(sp);
135: }
136:
137: /*
138: * Output any debug information at the current lexical
139: * level -- this will generally be typedef/struct/union/enum
140: * definitions, and when llex is < LL_EXT the external
141: * references which have been used.
142: */
143: dbdown()
144: {
145: register SYM *tsp;
146: register int c;
147: register TOK *tp;
148: register int i;
149: int changes;
150:
151: if (notvariant(VDEBUG) && notvariant(VTYPES))
152: return;
153: /* External references */
154: if (llex < LL_EXT) {
155: for (i=0; i < NHASH; i+=1)
156: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) {
157: for (tsp = tp->t_sym; tsp != NULL; tsp = tsp->s_sp) {
158: if (tsp->s_slevel < SL_VAR)
159: continue;
160: c = tsp->s_class;
161: if ((tsp->s_flag&S_USED) != 0
162: && (c==C_GREF || c==C_CXT))
163: dbdecl(tsp);
164: }
165: }
166: }
167: /* Type definitions */
168: do {
169: changes = 0;
170: for (i=0; i < NHASH; i+=1)
171: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) {
172: for (tsp = tp->t_sym; tsp != NULL; tsp = tsp->s_sp) {
173: if (tsp->s_slevel < SL_VAR)
174: continue;
175: if (tsp->s_level <= llex)
176: continue;
177: c = tsp->s_class;
178: if (istype(c)
179: && (tsp->s_flag&S_USED) != 0
180: && (tsp->s_flag&S_SYMB) == 0) {
181: tsp->s_flag |= S_SYMB;
182: changes += 1;
183: dbdecl(tsp);
184: }
185: }
186: }
187: } while (changes);
188: }
189:
190: /*
191: * Given a symbol, see if typedef or tagged type is defined for it.
192: */
193: static
194: SYM *
195: findtype(sp)
196: register SYM *sp;
197: {
198: register int i;
199:
200: i = sp->s_type;
201: if (i==T_FSTRUCT || i==T_FUNION || i==T_FENUM)
202: return (sp->s_ip);
203: if (i!=T_STRUCT && i!=T_UNION && i!=T_ENUM)
204: return (NULL);
205: return (taglookup(sp->s_ip));
206: }
207:
208: /*
209: * Write a symbol entry in intermediate format.
210: */
211:
212: static char tmap[] = {
213: DT_NONE,
214: DT_CHAR,
215: DT_UCHAR,
216: DT_SHORT,
217: DT_USHORT,
218: DT_INT,
219: DT_UINT,
220: -1, /* T_PTR */
221: DT_LONG,
222: DT_ULONG,
223: DT_FLOAT,
224: DT_DOUBLE,
225: DT_VOID,
226: DT_STRUCT,
227: DT_STRUCT, /* T_FSTRUCT */
228: DT_UNION,
229: DT_UNION, /* T_FUNION */
230: DT_ENUM,
231: DT_ENUM /* T_FENUM */
232: };
233:
234: static char dmap[] = {
235: DD_PTR,
236: DD_FUNC,
237: DD_ARRAY,
238: -1 /* D_MOSAR */
239: };
240:
241: static char cmap[] = {
242: -1, /* C_NONE */
243: DC_AUTO,
244: DC_SIN,
245: DC_SEX,
246: DC_GDEF,
247: DC_GREF,
248: -1, /* C_ARG */
249: DC_GREF, /* C_CXT */
250: DC_LAB,
251: -1, /* C_FREF */
252: -1, /* C_KEY */
253: DC_TYPE,
254: DC_REG,
255: DC_STAG,
256: DC_UTAG,
257: DC_ETAG,
258: DC_MOS,
259: DC_MOU,
260: DC_MOE,
261: DC_PAUTO,
262: DC_PREG
263: };
264:
265: dbpr(sp) register SYM *sp;
266: {
267: register int n;
268: int t;
269:
270: /* Identify class-segment */
271: if ((n = cmap[sp->s_class]) < 0)
272: dfatal(__LINE__);
273: bput(n);
274:
275: /* Put line number */
276: if (istackp < istack+NLEV)
277: iput((ival_t) istack[NLEV-1].i_line);
278: else
279: iput((ival_t) sp->s_dline);
280:
281: /* Identify value */
282: if (n < DC_AUTO) {
283: ; /* No value */
284: } else if (n < DC_MOS) {
285: iput((ival_t) sp->s_value);
286: } else {
287: bput(sp->s_width);
288: bput(sp->s_offset);
289: iput((ival_t) sp->s_value);
290: }
291:
292: /* Identify symbol */
293: if (n < DC_TYPE) /* Global */
294: nput(sp->s_id);
295: else if (n < DC_FILE) /* Type name */
296: sput(sp->s_id);
297: else /* Local */
298: sput(sp->s_id);
299:
300: /* Get a real type name */
301: if ((t = sp->s_type) == T_NONE) {
302: switch (sp->s_class) {
303: case C_STAG: t = T_STRUCT; break;
304: case C_UTAG: t = T_UNION; break;
305: case C_ETAG: t = T_ENUM; break;
306: case C_MOE:
307: case C_LAB: t = T_NONE; break;
308: default: dfatal(__LINE__); break;
309: }
310: }
311:
312: /* Generate dimension string */
313: if (notvariant(VTYPES)) {
314: bput(DT_NONE);
315: zput((sizeof_t)0);
316: } else {
317: register DIM *dp;
318:
319: for (dp = sp->s_dp; dp != NULL; dp = dp->d_dp) {
320: if ((n = dmap[dp->d_type]) < 0)
321: dfatal(__LINE__);
322: bput(n);
323: zput(tidsize(t, sp->s_ip, dp, 0));
324: }
325:
326: /* Generate type string */
327: if ((n = tmap[t]) < 0)
328: dfatal(__LINE__);
329: bput(n);
330: zput(tidsize(t, sp->s_ip, dp, 0));
331:
332: /* Generate tag string */
333: if (n==DT_STRUCT || n==DT_UNION || n==DT_ENUM)
334: dbinfo(sp);
335: }
336: }
337:
338: static dbinfo(sp) SYM *sp;
339: {
340: register INFO *ip;
341: register SYM **ssp;
342: register int i;
343:
344: if ((ip = sp->s_ip) == NULL)
345: dfatal(__LINE__);
346: if ( ! istag(sp->s_class) && (sp = findtype(sp)) != NULL) {
347: sp->s_flag |= S_USED;
348: bput(DX_NAME);
349: zput((sizeof_t)0);
350: sput(sp->s_id);
351: return;
352: }
353:
354: i = ip->i_nsp;
355: ssp = ip->i_sp;
356: bput(DX_MEMBS);
357: zput((sizeof_t)i);
358: while (--i >= 0) dbpr(*ssp++);
359: return;
360: }
361:
362: dfatal(line)
363: {
364: cbotch("bad value in debug on line %d", line);
365: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.