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