|
|
1.1 root 1: /*
2: * C compiler.
3: * Read class and type.
4: * Includes "readonly" and "alien" adjectives.
5: */
6: #ifdef vax
7: #include "INC$LIB:cc0.h"
8: #else
9: #include "cc0.h"
10: #endif
11:
12: /*
13: * Tables used to map keyword into class and type value.
14: */
15: static short tmtab[] = {
16: T_INT,
17: T_CHAR,
18: T_FLOAT,
19: T_DOUBLE,
20: T_VOID
21: };
22:
23: static short cmtab[] = {
24: C_GREF,
25: C_SIN,
26: C_REG,
27: C_TYPE,
28: C_AUTO
29: };
30:
31: /*
32: * Read a class and type specification in a declaration.
33: * Store the class, type, dimension list pointer and structure info
34: * list pointer back through the supplied reference arguments.
35: * Set the readonly flag indirectly through the pointer.
36: * On entry, 's' is the first token of the declaration;
37: * on exit, 's' is the first token beyond the declaration.
38: */
39: gcandt(ac, at, adp, aip, rfp)
40: int *ac, *at;
41: DIM **adp;
42: INFO **aip;
43: int *rfp;
44: {
45: register SYM *sp;
46: register int c;
47: int t;
48: DIM *dp;
49: INFO *ip;
50: int rf, af; /* readonly, alien */
51: int sf, lf, uf; /* short, long, unsigned */
52: int cf, vf, nf; /* const, volatile, signed */
53:
54: c = C_NONE;
55: t = T_NONE;
56: dp = ip = NULL;
57: rf = af = 0;
58: sf = lf = uf = 0;
59: cf = vf = nf = 0;
60: for (;;) {
61: switch (s) {
62:
63: case SHORT: ++sf; break;
64: case LONG: ++lf; break;
65: case UNSIGNED: ++uf; break;
66: case SIGNED: ++nf; break;
67: case READONLY: ++rf; break;
68: case ALIEN: ++af; break;
69: /* These two should become the first DIM's modifying the base type */
70: /* if they appear here or first in the declarator */
71: case CONST: ++cf; break;
72: case VOLATILE: ++vf; break;
73:
74: case INT:
75: case CHAR:
76: case FLOAT:
77: case DOUBLE:
78: case VOID:
79: mdeftype(t, &ip);
80: t = tmtab[s-INT];
81: break;
82:
83: case STRUCT:
84: case UNION:
85: mdeftype(t, &ip);
86: gstruct(c, &t, &ip);
87: continue;
88:
89: case ENUM:
90: mdeftype(t, &ip);
91: genum(c, &t, &ip);
92: continue;
93:
94: case EXTERN:
95: case STATIC:
96: case REGISTER:
97: case TYPEDEF:
98: case AUTO:
99: if (c != C_NONE)
100: cerror("multiple classes");
101: c = cmtab[s-EXTERN];
102: break;
103:
104: case ID:
105: if (t == T_NONE) {
106: sp = reflookup(SL_VAR);
107: if (sp!=NULL && sp->s_class==C_TYPE) {
108: t = sp->s_type;
109: dp = sp->s_dp;
110: ip = sp->s_ip;
111: sp->s_flag |= S_USED;
112: if (t==T_STRUCT || t==T_UNION
113: || t==T_ENUM)
114: ++ip->i_refc;
115: break;
116: }
117: }
118: /* Fall through */
119:
120: default:
121: if (sf+lf>1 || rf>1 || af>1 || uf+nf>1 || cf>1 || vf>1)
122: cerror("too many adjectives");
123: if (lf) {
124: if (t == T_FLOAT)
125: t = T_DOUBLE;
126: else if (t == T_DOUBLE)
127: t = T_DOUBLE; /* uh, T_LDOUBLE */
128: else if (t == T_INT)
129: t = T_LONG;
130: else if (t == T_NONE)
131: t = T_LONG;
132: else
133: cerror("inappropriate \"long\"");
134: }
135: if (sf) {
136: if (t == T_INT)
137: t = T_SHORT;
138: else if (t == T_NONE)
139: t = T_SHORT;
140: else
141: cerror("inappropriate \"short\"");
142: }
143: if (uf) {
144: if (t > T_LONG)
145: cerror("inappropriate \"unsigned\"");
146: else if (t == T_NONE)
147: t = T_UINT;
148: else
149: ++t; /* Magic */
150: }
151: if (nf) {
152: if (t > T_LONG)
153: cerror("inappropriate \"signed\"");
154: else if (t == T_NONE)
155: t = T_INT;
156: }
157: if (cf || vf) {
158: if (t == T_NONE)
159: t = T_INT;
160: }
161: if (t==T_UCHAR || t==T_USHORT || t==T_ULONG
162: || t==T_ENUM || t==T_FENUM
163: || t==T_VOID || rf!=0 || af != 0)
164: notbook();
165: *ac = c;
166: *at = t;
167: *adp = dp;
168: *aip = ip;
169: *rfp = 0;
170: if (rf)
171: *rfp |= S_RONLY;
172: if (af)
173: *rfp |= S_ALIEN;
174: return;
175: }
176: lex();
177: }
178: }
179:
180: /*
181: * Check if we already have a type.
182: * If so, complain (we are about to get another)
183: * and keep the reference count of the info structure correct.
184: */
185: mdeftype(t, aip)
186: register int t;
187: register INFO **aip;
188: {
189: if (t != T_NONE) {
190: cerror("multiple types");
191: xdropinfo(t, *aip);
192: *aip = NULL;
193: }
194: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.