1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)yyid.c 5.1 (Berkeley) 6/5/85";
9: #endif not lint
10:
11: #include "whoami.h"
12: #include "0.h"
13: #include "tree_ty.h" /* must be included for yy.h */
14: #include "yy.h"
15:
16: #ifdef PI
17: extern union semstack *yypv;
18: /*
19: * Determine whether the identifier whose name
20: * is "cp" can possibly be a kind, which is a
21: * namelist class. We look through the symbol
22: * table for the first instance of cp as a non-field,
23: * and at all instances of cp as a field.
24: * If any of these are ok, we return true, else false.
25: * It would be much better to handle with's correctly,
26: * even to just know whether we are in a with at all.
27: *
28: * Note that we don't disallow constants on the lhs of assignment.
29: */
30: identis(cp, kind)
31: register char *cp;
32: int kind;
33: {
34: register struct nl *p;
35: int i;
36:
37: /*
38: * Cp is NIL when error recovery inserts it.
39: */
40: if (cp == NIL)
41: return (1);
42:
43: /*
44: * Record kind we want for possible later use by yyrecover
45: */
46: yyidwant = kind;
47: yyidhave = NIL;
48: i = ( (int) cp ) & 077;
49: for (p = disptab[i]; p != NIL; p = p->nl_next)
50: if (p->symbol == cp) {
51: if (yyidok(p, kind))
52: goto gotit;
53: if (p->class != FIELD && p->class != BADUSE)
54: break;
55: }
56: if (p != NIL)
57: for (p = p->nl_next; p != NIL; p = p->nl_next)
58: if (p->symbol == cp && p->class == FIELD && yyidok(p, kind))
59: goto gotit;
60: return (0);
61: gotit:
62: if (p->class == BADUSE && !Recovery) {
63: yybadref(p, OY.Yyeline);
64: yypv[0].i_entry = NIL;
65: }
66: return (1);
67: }
68:
69: /*
70: * A bad reference to the identifier cp on line
71: * line and use implying the addition of kindmask
72: * to the mask of kind information.
73: */
74: struct nl *
75: yybaduse(cp, line, kindmask)
76: register char *cp;
77: int line, kindmask;
78: {
79: register struct nl *p, *oldp;
80: int i;
81:
82: i = ( (int) cp ) & 077;
83: for (p = disptab[i]; p != NIL; p = p->nl_next)
84: if (p->symbol == cp)
85: break;
86: oldp = p;
87: if (p == NIL || p->class != BADUSE)
88: p = enter(defnl(cp, BADUSE, NLNIL, 0));
89: p->value[NL_KINDS] |= kindmask;
90: yybadref(p, line);
91: return (oldp);
92: }
93:
94: /*
95: * ud is initialized so that esavestr will allocate
96: * sizeof ( struct udinfo ) bytes for the 'real' struct udinfo
97: */
98: struct udinfo ud = { ~0 , (struct udinfo *) ~0 , 0};
99: /*
100: * Record a reference to an undefined identifier,
101: * or one which is improperly used.
102: */
103: yybadref(p, line)
104: register struct nl *p;
105: int line;
106: {
107: register struct udinfo *udp;
108:
109: if (p->chain != NIL && ((struct udinfo *) p->chain)->ud_line == line)
110: return;
111: udp = (struct udinfo *) esavestr((char *) &ud);
112: udp->ud_line = line;
113: udp->ud_next = (struct udinfo *) p->chain;
114: p->chain = (struct nl *) udp;
115: }
116:
117: #define varkinds ((1<<CONST)|(1<<VAR)|(1<<REF)|(1<<ARRAY)|(1<<PTR) \
118: |(1<<RECORD)|(1<<FIELD)|(1<<FUNC)|(1<<FVAR) \
119: |(1<<FFUNC)|(1<<PROC)|(1<<FPROC))
120: /*
121: * Is the symbol in the p entry of the namelist
122: * even possibly a kind kind? If not, update
123: * what we have based on this encounter.
124: */
125: yyidok(p, kind)
126: register struct nl *p;
127: int kind;
128: {
129:
130: if (p->class == BADUSE) {
131: if (kind == VAR)
132: return (p->value[0] & varkinds);
133: return (p->value[0] & (1 << kind));
134: }
135: if (yyidok1(p, kind))
136: return (1);
137: if (yyidhave != NIL)
138: yyidhave = IMPROPER;
139: else
140: yyidhave = p->class;
141: return (0);
142: }
143:
144: yyidok1(p, kind)
145: register struct nl *p;
146: int kind;
147: {
148:
149: switch (kind) {
150: default:
151: case FUNC:
152: return ( p -> class == FUNC
153: || p -> class == FVAR
154: || p -> class == FFUNC );
155: case PROC:
156: return ( p -> class == PROC || p -> class == FPROC );
157: case CONST:
158: case TYPE:
159: case FIELD:
160: return (p->class == kind);
161: case VAR:
162: return (p->class == CONST || yyisvar(p, NIL));
163: case ARRAY:
164: case RECORD:
165: return (yyisvar(p, kind));
166: case PTRFILE:
167: return (yyisvar(p, PTR) || yyisvar(p, FILET));
168: }
169: }
170:
171: yyisvar(p, varclass)
172: register struct nl *p;
173: int varclass;
174: {
175:
176: switch (p->class) {
177: case FIELD:
178: case VAR:
179: case REF:
180: case FVAR:
181: /*
182: * We would prefer to return
183: * parameterless functions only.
184: */
185: case FUNC:
186: case FFUNC:
187: return (varclass == NIL || (p->type != NIL && p->type->class == varclass));
188: case PROC:
189: case FPROC:
190: return ( varclass == NIL );
191: }
192: return (0);
193: }
194: #endif
195: #ifdef PXP
196: #ifndef DEBUG
197: identis()
198: {
199:
200: return (1);
201: }
202: #endif
203: #ifdef DEBUG
204: extern char *classes[];
205:
206: char kindchars[] "UCTVAQRDPF";
207: /*
208: * Fake routine "identis" for pxp when testing error recovery.
209: * Looks at letters in variable names to answer questions
210: * about attributes. Mapping is
211: * C const_id
212: * T type_id
213: * V var_id also if any of AQRDF
214: * A array_id
215: * Q ptr_id
216: * R record_id
217: * D field_id D for "dot"
218: * P proc_id
219: * F func_id
220: */
221: identis(cp, kind)
222: register char *cp;
223: int kind;
224: {
225: register char *dp;
226: char kindch;
227:
228: /*
229: * Don't do anything unless -T
230: */
231: if (!typetest)
232: return (1);
233:
234: /*
235: * Inserted symbols are always correct
236: */
237: if (cp == NIL)
238: return (1);
239: /*
240: * Set up the names for error messages
241: */
242: yyidwant = classes[kind];
243: for (dp = kindchars; *dp; dp++)
244: if (any(cp, *dp)) {
245: yyidhave = classes[dp - kindchars];
246: break;
247: }
248:
249: /*
250: * U in the name means undefined
251: */
252: if (any(cp, 'U'))
253: return (0);
254:
255: kindch = kindchars[kind];
256: if (kindch == 'V')
257: for (dp = "AQRDF"; *dp; dp++)
258: if (any(cp, *dp))
259: return (1);
260: return (any(cp, kindch));
261: }
262: #endif
263: #endif
Defined functions
Defined variables
sccsid
defined in line
8;
never used
ud
defined in line
98; used 1 times
Defined macros