|
|
1.1 root 1: /*
2: * The routines in this file deal with the declaration of names.
3: * The declaration stuff is done here; the parsing is done elsewhere.
4: */
5: #ifdef vax
6: #include "INC$LIB:cc0.h"
7: #else
8: #include "cc0.h"
9: #endif
10:
11: /*
12: * This array maps function and parameter types
13: * into their defined interface types.
14: * fixtype() below knows about this table;
15: * if it changes, fixtype() might change too.
16: */
17: static char xtype[] = {
18: T_NONE, /* T_NONE, */
19: T_INT, T_UINT, /* T_CHAR, T_UCHAR, */
20: T_INT, T_UINT, /* T_SHORT, T_USHORT, */
21: T_INT, T_UINT, /* T_INT, T_UINT, */
22: T_PTR, /* T_PTR, */
23: T_LONG, T_ULONG, /* T_LONG, T_ULONG, */
24: T_DOUBLE, T_DOUBLE, /* T_FLOAT, T_DOUBLE, */
25: T_VOID, /* T_VOID, */
26: T_STRUCT, T_FSTRUCT, /* T_STRUCT, T_FSTRUCT, */
27: T_UNION, T_FUNION, /* T_UNION, T_FUNION, */
28: T_INT, T_INT /* T_ENUM, T_FENUM */
29: };
30:
31: /*
32: * Declare a variable 'sp' with class 'c', type 't' and structure info 'ip'.
33: * Many checks are made here for redeclarations and funny things.
34: * For objects of class 'C_MOE', 'x1' is the enumeration value.
35: * For objects of class 'C_MOS' and 'C_MOU',
36: * 'x1' is the field width in bits and 'x2' is the long offset in bits.
37: * 'ronlyf' passes both 'readonly' and 'alien' modifiers.
38: */
39: SYM *
40: declare(sp, c, t, ndp, ip, ronlyf, x1, x2)
41: register SYM *sp;
42: DIM *ndp;
43: INFO *ip;
44: unsigned long x2;
45: {
46: register DIM *dp, *xdp;
47: int af, ff, rf;
48: int oc, ot;
49: unsigned long value;
50: unsigned offs;
51:
52: /*
53: * Demote some function definitions to references.
54: * Adjust the return type of functions returning char, short or float.
55: * If the s_level is wrong, due to missing "extern", check
56: * for redeclaration.
57: */
58: if (ndp!=NULL && ndp->d_type==D_FUNC) {
59: if (c==C_AUTO || c==C_PAUTO || c==C_SIN
60: || ((c==C_GDEF || c==C_SEX) && (s==SEMI || s==COMMA)))
61: c = C_GREF;
62: if (ndp->d_dp==NULL && ((ronlyf&S_ALIEN)==0 || t==T_FLOAT))
63: t = fixtype(t, sp, "function");
64: if (sp->s_level > LL_EXT)
65: sp = fixlevel(sp);
66: }
67: /*
68: * Make certain that the declarator is not
69: * forbidden by the semantics of C. The declaration
70: * reader allows anything that exhibits correct
71: * syntax through.
72: */
73: if (c!=C_TYPE && t==T_VOID && !isfunction(ndp)) {
74: cerror("illegal use of \"void\" type");
75: t = T_INT;
76: }
77: af = ff = rf = 0;
78: for (dp=ndp; dp!=NULL; dp=dp->d_dp) {
79: switch (dp->d_type) {
80:
81: case D_ARRAY:
82: if (ff != 0)
83: cerror("function cannot return an array");
84: if ((xdp = dp->d_dp) != NULL /* [10][] */
85: && xdp->d_type == D_ARRAY
86: && xdp->d_bound == 0)
87: cerror("bad flexible array declaration");
88: af = 1;
89: ff = 0;
90: break;
91:
92: case D_FUNC:
93: if (ff != 0)
94: cerror("function cannot return a function");
95: else if (af != 0)
96: cerror("cannot declare array of functions");
97: af = 0;
98: ff = 1;
99: break;
100:
101: case D_PTR:
102: af = ff = 0;
103: }
104: }
105: if (ff!=0 && istruct(t))
106: notbook();
107: /*
108: * Check for redeclarations.
109: * If the old is "C_ARG" (a function parameter),
110: * then just about any combination is ok.
111: * The types are adjusted in consideration of the passing rules.
112: * Other redeclarations are typechecked.
113: */
114: ot = sp->s_type;
115: oc = sp->s_class;
116: if (oc == C_ARG) {
117: dp = ndp;
118: if (dp == NULL || isfunction(dp)) {
119: t = fixtype(t, sp, "parameter");
120: if (istruct(t))
121: notbook();
122: } else if (dp->d_type == D_ARRAY) {
123: dp->d_type = D_PTR;
124: dp->d_bound = 0;
125: } else if (dp->d_type != D_PTR)
126: cerror("functions cannot be parameters");
127: } else if (c==C_PAUTO || c==C_PREG) {
128: cerror("identifier \"%s\" is not a parameter", sp->s_id);
129: c = C_AUTO;
130: } else if ((c==C_AUTO || c==C_REG)
131: && ndp!=NULL && ndp->d_type==D_ARRAY && ndp->d_bound==0) {
132: cerror("cannot declare flexible automatic array");
133: } else if (ot!=T_NONE && ot!=t && !ismemb(oc)) {
134: ++rf;
135: } else if (oc == C_CXT) {
136: if (ndp == NULL || ndp->d_type != D_FUNC || ronlyf != 0)
137: ++rf;
138: } else if (oc==C_MOE && c==C_MOE) {
139: if (sp->s_value != x1)
140: ++rf;
141: } else if (ismemb(oc) && ismemb(c)) {
142: value = x2/NBPBYTE;
143: offs = x2%NBPBYTE;
144: if (doalign(t) && x1 != 0 && (value&1) != 0) {
145: --value;
146: offs += 8;
147: }
148: if (x1 != sp->s_width
149: || value != sp->s_value
150: || offs != sp->s_offset)
151: ++rf;
152: } else if (isdefn(oc) && isdefn(c)) {
153: if (oc!=C_GREF && c!=C_GREF)
154: ++rf;
155: else if (c == C_GREF)
156: c = oc;
157: } else if (oc != C_NONE)
158: ++rf;
159: if (oc != C_NONE && (sp->s_flag&ronlyf) != ronlyf)
160: ++rf;
161: sp->s_class = c;
162: sp->s_type = t;
163: dropdim(sp->s_dp);
164: sp->s_dp = ndp;
165: sp->s_dline = line;
166: sp->s_flag |= ronlyf;
167: if ((ronlyf&S_ALIEN) != 0) {
168: if ( ! isdefn(c) || ndp==NULL || ndp->d_type!=D_FUNC)
169: cerror("inappropriate \"alien\" modifier");
170: sp->s_seg = SALIEN;
171: }
172: if (istag(oc) || ot==T_STRUCT || ot==T_UNION || ot==T_ENUM) {
173: dropinfo(sp->s_ip);
174: sp->s_ip = NULL;
175: }
176: if (istag(c) || t>T_DOUBLE) {
177: sp->s_ip = ip;
178: if (istag(c) || t==T_STRUCT || t==T_UNION || t==T_ENUM)
179: ++ip->i_refc;
180: }
181: if (istag(c))
182: backplug(sp);
183: if (c == C_MOE)
184: sp->s_value = x1;
185: if (ismemb(c)) {
186: value = x2/NBPBYTE;
187: offs = x2%NBPBYTE;
188: if (doalign(t) && x1 != 0 && (value&1) != 0) {
189: --value;
190: offs += 8;
191: }
192: if (value > MAXMEMB)
193: cerror("member \"%s\" is not addressable", sp->s_id);
194: sp->s_width = x1;
195: sp->s_value = value;
196: sp->s_offset = offs;
197: }
198: if (rf != 0)
199: cerror("identifier \"%s\" is being redeclared", sp->s_id);
200: return(sp);
201: }
202:
203: /*
204: * Decrement reference count of a
205: * structure info. block.
206: * Free it if the block is now an
207: * unreferenced one.
208: */
209: dropinfo(ip)
210: register INFO *ip;
211: {
212: if (ip!=NULL && --ip->i_refc==0)
213: free((char *) ip);
214: }
215:
216: /*
217: * Test if a storage class is a global
218: * storage class.
219: */
220: isdefn(c)
221: register int c;
222: {
223: if (c==C_GDEF || c==C_GREF || c==C_SEX || c==C_SIN)
224: return (1);
225: return (0);
226: }
227:
228: /*
229: * Test if a type is one of the structure
230: * like types.
231: */
232: istruct(t)
233: {
234: if (t>=T_STRUCT && t<=T_FUNION)
235: return (1);
236: return (0);
237: }
238:
239: /*
240: * Test for tag classes.
241: */
242: istag(c)
243: register int c;
244: {
245: if (c==C_STAG || c==C_UTAG || c==C_ETAG)
246: return (1);
247: return (0);
248: }
249:
250: /*
251: * Test for one of the type definition classes.
252: */
253: istype(c)
254: register int c;
255: {
256: if (c==C_STAG || c==C_UTAG || c==C_ETAG || c==C_TYPE)
257: return (1);
258: return (0);
259: }
260:
261: /*
262: * Test for member classes.
263: */
264: ismemb(c)
265: register int c;
266: {
267: if (c==C_MOS || c==C_MOU)
268: return (1);
269: return (0);
270: }
271:
272: /*
273: * Examine a "DIM" chain to see if it describes a function.
274: */
275: isfunction(dp)
276: register DIM *dp;
277: {
278: register int n;
279:
280: for (n = 0; dp!=NULL; dp = dp->d_dp)
281: n = (dp->d_type == D_FUNC);
282: return (n);
283: }
284:
285: /*
286: * Given a type t, return the adjusted type xtype[t].
287: * Issue a "type adjusted" warning for dangerous cases.
288: * This does not determine "dangerous" rigorously,
289: * rather it uses facts about the values in xtype[] above;
290: * the only cases in which xtype[t]!=t are
291: * char->int, uchar->uint, short->int, ushort->uint, float->double.
292: */
293: fixtype(t, sp, s)
294: register int t;
295: SYM *sp;
296: char *s;
297: {
298: register int xt;
299: char *ntype;
300:
301: xt = xtype[t];
302: if (xt != t && mysizes[xt] != mysizes[t]) {
303: switch(xt) {
304: case T_INT:
305: ntype = "int";
306: break;
307: case T_UINT:
308: ntype = "unsigned int";
309: break;
310: case T_DOUBLE:
311: ntype = "double";
312: break;
313: }
314: if (isvariant(VWIDEN))
315: cwarn("type of %s \"%s\" adjusted to %s", s, sp->s_id, ntype);
316: }
317: return(xt);
318: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.