|
|
1.1 root 1: /*
2: * C compiler.
3: * Symbol table routines.
4: */
5: #ifdef vax
6: #include "INC$LIB:cc0.h"
7: #else
8: #include "cc0.h"
9: #endif
10:
11: /*
12: * Compare a token to id[] for equality.
13: */
14: ideq(tp) TOK *tp;
15: {
16: register int *ip1, *ip2, n;
17: ip1 = tp->t_id;
18: ip2 = id;
19: n = (idsize+2)>>1;
20: while (--n >= 0)
21: if (*ip1++ != *ip2++)
22: return 0;
23: return 1;
24: }
25:
26: /*
27: * Create a new token with id[]
28: * and return a pointer.
29: */
30: TOK *newtoken()
31: {
32: register TOK *tp;
33:
34: tp = (TOK *)new(sizeof(TOK) + ((idsize+2)&~1));
35: tp->t_tp = NULL;
36: tp->t_sym = NULL;
37: strncpy(tp->t_id, id, (idsize+2)&~1);
38: return tp;
39: }
40:
41: /*
42: * Allocate a new symbol node.
43: */
44: SYM *newsym()
45: {
46: register SYM *sp;
47:
48: sp = (SYM *) new(sizeof(SYM));
49: zero(sp, sizeof(SYM));
50: sp->s_seg = SANY;
51: sp->s_id = idp->t_id;
52: return (sp);
53: }
54:
55: /*
56: * Allocate a new cpp symbol
57: */
58: CPPSYM *newcpp(narg, value, nval) int narg; char *value; int nval;
59: {
60: register CPPSYM *sp;
61:
62: sp = (CPPSYM *) new(sizeof(CPPSYM)+nval);
63: sp->s_slevel = SL_CPP;
64: sp->s_narg = narg;
65: sp->s_value = narg >= 0 ? XUSERA : XUSER;
66: strcpy(sp->s_body, value);
67: return (sp);
68: }
69:
70: /*
71: * Search a symbol list for a symbol pointer
72: */
73: SYM *memberp(sp, splist) register SYM *sp, *splist;
74: {
75: while (splist != NULL)
76: if (sp == splist)
77: return splist;
78: else
79: splist = splist->s_sp;
80: return splist;
81: }
82:
83: /*
84: * Look up the name in 'id' in a reference context.
85: * The name may appear at any lexic level.
86: */
87: SYM *reflookup(ls) register int ls;
88: {
89: register SYM *sp;
90:
91: for (sp = idp->t_sym; sp != NULL; sp = sp->s_sp)
92: if (sp->s_slevel < ls)
93: continue;
94: else if (sp->s_slevel == ls)
95: return sp;
96: else
97: break;
98: return(NULL);
99: }
100:
101: /*
102: * Look up the identifier in 'id' in the context of a declaration.
103: * If the symbol is not found, it is created.
104: * The argument 'll' is the lexic level to search in.
105: * The argument 'ls' is the symbol class to search.
106: */
107: SYM *deflookup(ls, ll) int ls, ll;
108: {
109: register SYM *sp, **spp;
110:
111: for (spp = &idp->t_sym; (sp = *spp) != NULL; spp = &sp->s_sp)
112: if (sp->s_slevel < ls)
113: continue;
114: else if (sp->s_slevel == ls) {
115: if (sp->s_level == ll)
116: return (sp);
117: else if (sp->s_level < ll) {
118: if (sp->s_level == LL_ARG && ll >= LL_AUTO)
119: cwarn("parameter \"%s\" redeclared as automatic",
120: sp->s_id);
121: break;
122: } else
123: continue;
124: } else
125: break;
126: *spp = newsym();
127: (*spp)->s_sp = sp;
128: sp = *spp;
129: sp->s_slevel = ls;
130: sp->s_level = ll;
131: return (sp);
132: }
133:
134: /*
135: * Look up a member of a structure.
136: */
137: SYM *moslookup(tp) TREE *tp;
138: {
139: INFO *ip;
140: register SYM *sp, *sp2;
141: register int i;
142:
143: sp = idp->t_sym;
144: /* First search using info of left hand context */
145: if ((tp->t_type==T_STRUCT || tp->t_type==T_UNION)
146: && (ip=tp->t_ip)!=NULL) {
147: for (i=0; i<ip->i_nsp; i+=1) {
148: sp2 = ip->i_sp[i];
149: if (memberp(sp2, sp))
150: return (sp2);
151: }
152: }
153: /* Now search for unambiguous reference */
154: for (sp2 = NULL; sp != NULL; sp = sp->s_sp) {
155: if (sp->s_slevel < SL_MOS)
156: continue;
157: if (sp2 == NULL) {
158: sp2 = sp;
159: continue;
160: }
161: if (sp->s_value!=sp2->s_value
162: || sp->s_offset!=sp2->s_offset
163: || sp->s_width!=sp2->s_width) {
164: cerror("ambiguous reference to \"%s\"", id);
165: break;
166: }
167: }
168: return (sp2);
169: }
170:
171: /*
172: * Try to find a structure tag, given a pointer to an info structure.
173: * Used to hunt up the name of the structure
174: * when doing strict structure member checks.
175: */
176: SYM *taglookup(ip) register INFO *ip;
177: {
178: register SYM *sp;
179: register TOK *tp;
180: register int i;
181:
182: for (i=0; i<NHASH; ++i)
183: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) {
184: for (sp = tp->t_sym; sp != NULL; sp = sp->s_sp) {
185: if (sp->s_slevel != SL_TAG)
186: continue;
187: if (istag(sp->s_class) && sp->s_ip==ip)
188: return (sp);
189: }
190: }
191: return (NULL);
192: }
193:
194: /*
195: * Fake a definition.
196: * Put the name into the hash table with the specified flags.
197: * Set the type to int.
198: * The class will be auto or member, depending on the flags.
199: */
200: SYM *fakedef(ls) int ls;
201: {
202: register SYM *sp;
203:
204: sp = deflookup(ls, llex);
205: sp->s_type = T_INT;
206: sp->s_class = (ls == SL_MOS) ? C_MOS : C_AUTO;
207: sp->s_flag |= S_USED;
208: return (sp);
209: }
210:
211: /*
212: * 'sp' is a symbol pointer for an external function
213: * which was entered at local lexical level
214: * because no "extern" appeared in the declaration.
215: * Return a symbol pointer at the correct lexical level.
216: * This is a pathological case, not worth optimizing.
217: */
218: SYM *fixlevel(sp) register SYM *sp;
219: {
220: register SYM **tsp;
221:
222: /* Chase the chain for this identifier */
223: setid(sp->s_id);
224: for (tsp = &idp->t_sym; *tsp != sp; tsp = &(*tsp)->s_sp)
225: if (*tsp == NULL) cbotch("bad fixlevel");
226: *tsp = sp->s_sp;
227: free(sp);
228: if ((sp = reflookup(SL_VAR)) == NULL)
229: sp = deflookup(SL_VAR, LL_EXT);
230: return sp;
231: }
232:
233: /*
234: * Sweep through the symbol table,
235: * backplugging the structure data for any
236: * structures waiting for the definition
237: * of structure tag "tsp".
238: */
239: backplug(tsp)
240: register SYM *tsp;
241: {
242: register SYM *sp;
243: register int t;
244: register TOK *tp;
245: register int i;
246:
247: for (i=0; i<NHASH; ++i)
248: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) {
249: for (sp = tp->t_sym; sp != NULL; sp = sp->s_sp) {
250: if (sp->s_slevel < SL_VAR)
251: continue;
252: t = sp->s_type;
253: if ((t==T_FSTRUCT || t==T_FUNION || t==T_FENUM)
254: && sp->s_ip==tsp) {
255: --sp->s_type; /* Magic */
256: sp->s_ip = tsp->s_ip;
257: ++tsp->s_ip->i_refc;
258: }
259: }
260: }
261: }
262:
263: /*
264: * The lexic level has decremented.
265: * Delete symbol table entries associated with the old level.
266: * Look for undefined forward referenced labels
267: * and put out diagnostics for them.
268: */
269: downlex()
270: {
271: register SYM *sp, **spp;
272: register TOK *tp;
273: register int c, i;
274:
275: dbdown();
276: for (i=0; i<NHASH; ++i)
277: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) {
278: for (spp = &tp->t_sym; (sp = *spp) != NULL; ) {
279: if (sp->s_slevel < SL_VAR) {
280: spp = &sp->s_sp;
281: continue;
282: }
283: c = sp->s_class;
284: if (c==C_FREF && llex==LL_EXT)
285: cerror("label \"%s\" undefined", tp->t_id);
286: if (sp->s_level <= llex) {
287: spp = &sp->s_sp;
288: continue;
289: }
290: if ((c!=C_LAB && c!=C_FREF) || llex==LL_EXT) {
291: if (llex >= LL_EXT)
292: usedcheck(sp);
293: *spp = sp->s_sp;
294: free((char *) sp);
295: continue;
296: }
297: spp = &sp->s_sp;
298: }
299: }
300: }
301:
302: /*
303: * Put out the required warning if used checking is enabled.
304: */
305: usedcheck(sp) register SYM *sp;
306: {
307: register char *lp, *tp;
308: char lb[32];
309:
310: if ((sp->s_flag&S_USED) != 0)
311: return;
312: if (isvariant(VSUVAR)
313: || (isvariant(VSUREG) && sp->s_class==C_REG)) {
314: switch (sp->s_class) {
315: default:
316: tp = "variable";
317: break;
318: case C_REG:
319: tp = "register variable";
320: break;
321: case C_TYPE:
322: tp = "type definition";
323: break;
324: case C_LAB:
325: tp = "label";
326: break;
327: case C_NONE: /* for forward references */
328: case C_GREF:
329: case C_MOS:
330: case C_MOU:
331: case C_MOE:
332: case C_STAG:
333: case C_UTAG:
334: case C_ETAG:
335: return;
336: }
337: lp = "";
338: if (sp->s_dline != 0)
339: sprintf(lp = lb, " (line %d)", sp->s_dline);
340: cstrict("%s \"%s\"%s is not used", tp, sp->s_id, lp);
341: }
342: }
343:
344: /*
345: * Copy 'n' bytes.
346: */
347: copy(t, f, n)
348: register char *t, *f;
349: register int n;
350: {
351: while (--n >= 0)
352: *t++ = *f++;
353: }
354:
355: /*
356: * Zero 'n' bytes.
357: */
358: zero(p, n)
359: register char *p;
360: register int n;
361: {
362: while (--n >= 0)
363: *p++ = 0;
364: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.