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