mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
1092 lines
37 KiB
Plaintext
1092 lines
37 KiB
Plaintext
1File: DECL.C Page 1
|
|
1 /*
|
|
2 Copyright 1982
|
|
3 Alcyon Corporation
|
|
4 8716 Production Ave.
|
|
5 San Diego, Ca. 92121
|
|
6 */
|
|
7
|
|
8 #include "parser.h"
|
|
9 #define DTSIZE 077 /*data size in bytes*/
|
|
10 #define DREG 0100 /*data loadable into D-register?*/
|
|
11
|
|
12 char dinfo[] {
|
|
13 0, /*TYPELESS=0*/
|
|
14 1|DREG, /*CHAR=1*/
|
|
15 2|DREG, /*SHORT=2*/
|
|
16 2|DREG, /*INT=3*/
|
|
17 4|DREG, /*LONG=4*/
|
|
18 1|DREG, /*UCHAR=5*/
|
|
19 2|DREG, /*USHORT=6*/
|
|
20 2|DREG, /*UNSIGNED=7*/
|
|
21 4|DREG, /*ULONG=8*/
|
|
22 4|DREG, /*FLOAT=9[vlh]*/
|
|
23 4|DREG, /*DOUBLE=10[vlh]*/
|
|
24 0, /*STRUCT=11*/
|
|
25 0, /*FRSTRUCT=12*/
|
|
26 0, /*LLABEL=13*/
|
|
27 0, /*INVALID=14*/
|
|
28 0, /*INVALID=15*/
|
|
29 };
|
|
30
|
|
31 char aregtab[] { AREG5, AREG4, AREG3, 0 };
|
|
32 char dregtab[] { DREG7, DREG6, DREG5, DREG4, DREG3, 0 };
|
|
33 int inittype;
|
|
34
|
|
35 /*
|
|
36 * doextdef - external definition syntax
|
|
37 * This is fairly complicated since you do not know if you are
|
|
38 * parsing a external function declaration or a real function
|
|
39 * until after you've already scanned the argument list for the
|
|
40 * function. Basically you start off scanning an external declaration
|
|
41 * or function in the same way by collecting attributes, scanning
|
|
42 * the declarator, then scanning the function arguments if a function.
|
|
43 * At that point you look at the next token and if its a '{', keyword
|
|
44 * proceed accordingly.
|
|
45 * The C Syntax handled by this routine is (roughly):
|
|
46 * external_definition:
|
|
47 * function_definition
|
|
48 * data_definition
|
|
49 * function_definition:
|
|
50 * type_specifier function_declarator function_body
|
|
51 * function_declarator:
|
|
52 * declarator ( parameter_list )
|
|
53 * data_definition:
|
|
54 * EXTERNAL type_specifier init_declarator_list ;
|
|
55 * STATIC type_specifier init_declarator_list ;
|
|
56 */
|
|
57 doextdef() /* returns 0 for EOF or 1*/
|
|
58 {
|
|
59 register struct symbol *sp;
|
|
1File: DECL.C Page 2
|
|
60 register int dflag;
|
|
61 int sc, type;
|
|
62 long size;
|
|
63
|
|
64 if(!next(SEMI)) {
|
|
65 opap = exprp = exprarea;
|
|
66 sc = EXTERNAL;
|
|
67 type = (xflag?LONG:INT);
|
|
68 dflag = gettype(&sc,&type,&size);
|
|
69 if(type==STRUCT) /* deal with forward ref structures */
|
|
70 chksyms();
|
|
71 while( dodecl(sc,type,0,size), (sp=dsp) != 0 ) {
|
|
72 if( !dflag && notfunction(sp->s_type) ) {
|
|
73 synerr("external definition syntax");
|
|
74 return;
|
|
75 }
|
|
76 if( !stypedef(sp) && sc != STATIC )
|
|
77 if (notfunction(sp->s_type)) /*[vlh] .globl ext. vars*/
|
|
78 outextdef(sp->s_symbol);
|
|
79 if( notfunction(sp->s_type) ) { /*not function, check init*/
|
|
80 if( !stypedef(sp) ) {
|
|
81 doinit(sp);
|
|
82 if (sc == STATIC)
|
|
83 chksyms();
|
|
84 }
|
|
85 }
|
|
86 else if( peek(RESWORD) || peek(LCURBR) ||
|
|
87 (peek(SYMBOL) && stypedef(csp)) ) {
|
|
88 if(!stypedef(sp) && sc!=STATIC) /*[vlh] .globl local proc*/
|
|
89 outextdef(sp->s_symbol);
|
|
90 funcbody(sp);
|
|
91 return;
|
|
92 }
|
|
93 dsp = 0;
|
|
94 if( !next(COMMA) )
|
|
95 break;
|
|
96 }
|
|
97 if( gettok() != SEMI )
|
|
98 synerr("external definition syntax");
|
|
99 }
|
|
100 }
|
|
101
|
|
102 /*
|
|
103 * gettype - get attribute types in attribute list
|
|
104 * Handles single word keywords, such as int, char, etc. and also
|
|
105 * handles the declarations of structures and unions.
|
|
106 */
|
|
107 gettype(defsc,deftype,size) /* returns 0 for no type, 1 otherwise*/
|
|
108 int *defsc; /* default storage class*/
|
|
109 int *deftype; /* default data type*/
|
|
110 long *size; /* size of data element 3.4 int=>long*/
|
|
111 {
|
|
112 register int dtype, sc;
|
|
113 register int sflag, uflag, lflag, decflag;
|
|
114 register int token, stdflag, sbits;
|
|
115 long tsize;
|
|
116 register struct symbol *sp, *parent;
|
|
117
|
|
118 tdp = 0; tdflag = uflag = decflag = lflag = sflag = 0; tsize = 0L;
|
|
1File: DECL.C Page 3
|
|
119 dtype = TYPELESS;
|
|
120 sc = *defsc;
|
|
121 for( ; ; decflag++ ) {
|
|
122 if( (token=gettok()) == SYMBOL && stypedef(csp) ) {
|
|
123 dtype = 0;
|
|
124 tdp = csp;
|
|
125 continue;
|
|
126 }
|
|
127 if( token != RESWORD )
|
|
128 break;
|
|
129 switch( cvalue ) {
|
|
130
|
|
131 case R_TYPEDEF:
|
|
132 if( tdflag )
|
|
133 error("invalid typedef statement");
|
|
134 tdflag++;
|
|
135 continue;
|
|
136
|
|
137 case R_STATIC:
|
|
138 if( sc && sc != STATIC && sc != EXTERNAL )
|
|
139 error("invalid storage class");
|
|
140 sc = STATIC;
|
|
141 continue;
|
|
142
|
|
143 case R_AUTO:
|
|
144 if( sc && sc != AUTO )
|
|
145 error("invalid storage class");
|
|
146 sc = AUTO;
|
|
147 continue;
|
|
148
|
|
149 case R_EXTERNAL:
|
|
150 if( sc && sc != EXTERNAL )
|
|
151 error("invalid storage class");
|
|
152 sc = EXTERNAL;
|
|
153 continue;
|
|
154
|
|
155 case R_REGISTER:
|
|
156 if( sc && sc != REGISTER && sc != PDECLIST )
|
|
157 error("invalid register specification");
|
|
158 sc = REGISTER;
|
|
159 continue;
|
|
160
|
|
161 case R_LONG:
|
|
162 lflag++;
|
|
163 continue;
|
|
164
|
|
165 case R_SHORT:
|
|
166 sflag++;
|
|
167 continue;
|
|
168
|
|
169 case R_UNSIGNED:
|
|
170 uflag++;
|
|
171 continue;
|
|
172
|
|
173 case R_STRUCT:
|
|
174 cvalue = STRUCT;
|
|
175 case R_UNION:
|
|
176 stdflag = tdflag;
|
|
177 tdflag = 0; sp = 0;
|
|
1File: DECL.C Page 4
|
|
178 token = cvalue;
|
|
179 smember++;
|
|
180 if( next(SYMBOL) ) { /*struct [symbol] { ... }*/
|
|
181 sp = csp;
|
|
182 parent = csp;
|
|
183 strucptr[smember+instruct] = sp;
|
|
184 if( !sp->s_sc ) {
|
|
185 sp->s_attrib =| SDEFINED;
|
|
186 if(!infunc)
|
|
187 sp->s_attrib =| SGLOBAL;
|
|
188 sp->s_sc = STRPROTO;
|
|
189 sp->s_type = STRUCT;
|
|
190 sp->s_ssp = dalloc(0L);
|
|
191 }
|
|
192 if( sp->s_sc != STRPROTO )
|
|
193 error("redeclaration: %.8s",sp->s_symbol);
|
|
194 }
|
|
195 else parent = 0;
|
|
196 smember = 0;
|
|
197 if( next(LCURBR) ) {
|
|
198 instruct++;
|
|
199 strucptr[smember+instruct] = sp;
|
|
200 sbits = boffset;
|
|
201 boffset = 0;
|
|
202 tsize = dlist(token==STRUCT?STELCL:UNELCL);
|
|
203 boffset = sbits;
|
|
204 if(!next(RCURBR))
|
|
205 synerr("structure declaration syntax");
|
|
206 else if( sp ) {
|
|
207 if( dtab[sp->s_ssp] )
|
|
208 error("redeclaration: %.8s",sp->s_symbol);
|
|
209 dtab[sp->s_ssp] = tsize;
|
|
210 }
|
|
211 instruct--;
|
|
212 }
|
|
213 else if( !sp )
|
|
214 error("no structure name");
|
|
215 else if( sp->s_sc != STRPROTO )
|
|
216 error("invalid structure prototype: %.8s",sp->s_symbol);
|
|
217 else if( !dtab[sp->s_ssp] ) { /* FRSTRUCT */
|
|
218 token = FRSTRUCT;
|
|
219 if( ++frstp >= NFRSTR )
|
|
220 ferror("structure table overflow");
|
|
221 frstab[frstp] = sp;
|
|
222 }
|
|
223 else
|
|
224 tsize = dtab[sp->s_ssp];
|
|
225 tdflag = stdflag;
|
|
226 if( dtype != TYPELESS )
|
|
227 error("invalid type declaration");
|
|
228 dtype = (token == R_UNION) ? STRUCT : token;
|
|
229 continue;
|
|
230
|
|
231 case R_INT:
|
|
232 if( dtype != TYPELESS )
|
|
233 error("invalid type declaration");
|
|
234 dtype = INT;
|
|
235 continue;
|
|
236
|
|
1File: DECL.C Page 5
|
|
237 case R_CHAR:
|
|
238 if( dtype != TYPELESS )
|
|
239 error("invalid type declaration");
|
|
240 dtype = CHAR;
|
|
241 continue;
|
|
242
|
|
243 case R_FLOAT: /*[vlh] ver. 3.4*/
|
|
244 case R_DOUBLE:
|
|
245 if( dtype != TYPELESS )
|
|
246 error("invalid type declaration");
|
|
247 dtype = FLOAT;
|
|
248 continue;
|
|
249 }
|
|
250 break;
|
|
251 }
|
|
252 pbtok(token);
|
|
253 if( dtype == TYPELESS )
|
|
254 dtype = INT;
|
|
255 if(!sc)
|
|
256 sc = AUTO;
|
|
257 if( lflag ) { /*allow: long float, long int*/
|
|
258 if( dtype == INT )
|
|
259 dtype = LONG;
|
|
260 /* else if( dtype == FLOAT ) */
|
|
261 /* dtype = DOUBLE; */
|
|
262 else
|
|
263 error("invalid long declaration");
|
|
264 }
|
|
265 if( sflag ) {
|
|
266 if( dtype != INT )
|
|
267 error("invalid short declaration");
|
|
268 }
|
|
269 if( uflag ) {
|
|
270 if( dtype != INT ) /*allow: unsigned int*/
|
|
271 error("invalid unsigned declaration");
|
|
272 else
|
|
273 dtype = UNSIGNED;
|
|
274 }
|
|
275 if( !sflag && xflag && dtype == INT )
|
|
276 dtype = LONG;
|
|
277 *defsc = sc;
|
|
278 *deftype = dtype;
|
|
279 *size = tsize;
|
|
280 if (dtype == STRUCT || dtype == FRSTRUCT)
|
|
281 csp->s_struc = parent;
|
|
282 return(decflag);
|
|
283 }
|
|
284
|
|
285 /*
|
|
286 * dodecl - process a single declarator
|
|
287 * This does all the grubby handling of a single declarator given
|
|
288 * the attributes for the declarator. Handles typedef attributes
|
|
289 * adjusts offsets for structure elements, allocates register
|
|
290 * variables, etc.
|
|
291 */
|
|
292 long /* [vlh] 3.4 int => long */
|
|
293 dodecl(sc,type,offset,size) /* returns size of declarator*/
|
|
294 int sc; /* storage class*/
|
|
295 int type; /* data type*/
|
|
1File: DECL.C Page 6
|
|
296 int offset; /* offset if in structure or union*/
|
|
297 long size; /* size of single data item 3.4 i=> l*/
|
|
298 {
|
|
299 register struct symbol *sp;
|
|
300 register int redecf, stype, dtype, i, j;
|
|
301
|
|
302 if( peek(SEMI) || peek(RPAREN) )
|
|
303 return(0);
|
|
304 if( instruct && next(COLON) ) { /*handle bit filler field*/
|
|
305 if(!(i=cexpr()))
|
|
306 size = salign(INT,offset);
|
|
307 else
|
|
308 size = falign(type,i);
|
|
309 }
|
|
310 else if( (type=|declarator(0)) >= 0 && (sp=dsp) != 0 ) {
|
|
311 if( tdp ) /*typedef name in declaration*/
|
|
312 type = addtdtype(tdp,type,sp->s_dp,&(sp->s_ssp));
|
|
313 else if( btype(type) == STRUCT ) {
|
|
314 if( size )
|
|
315 sp->s_ssp = dalloc(size);
|
|
316 else
|
|
317 error("invalid structure declaration: %.8s",sp->s_symbol);
|
|
318 }
|
|
319 else if( btype(type) == FRSTRUCT )
|
|
320 sp->s_ssp = frstp;
|
|
321 redecf = 0;
|
|
322 switch( sp->s_sc ) { /*check for redeclarations.*/
|
|
323
|
|
324 case 0:
|
|
325 break;
|
|
326
|
|
327 case PARMLIST:
|
|
328 if( sc != PDECLIST && sc != REGISTER )
|
|
329 goto redec;
|
|
330 break;
|
|
331
|
|
332 case BFIELDCL:
|
|
333 if( sc != STELCL && sc != UNELCL )
|
|
334 goto redec;
|
|
335 break;
|
|
336
|
|
337 case STELCL:
|
|
338 case UNELCL:
|
|
339 redecf++;
|
|
340 break; /* [vlh] get rid of redecf entirely ?? */
|
|
341
|
|
342 case EXTERNAL:
|
|
343 if (sp->s_type == type) {
|
|
344 if (sc == sp->s_sc) break;
|
|
345 if (sc == AUTO && suptype(type) == FUNCTION) {
|
|
346 sc = EXTERNAL;
|
|
347 break;
|
|
348 }
|
|
349 }
|
|
350 default:
|
|
351 redec:
|
|
352 error("redeclaration: %.8s",sp->s_symbol);
|
|
353 return(size);
|
|
354 }
|
|
1File: DECL.C Page 7
|
|
355 sp->s_type = type;
|
|
356 dtype = suptype(type);
|
|
357 type = btype(type);
|
|
358 if( tdflag ) /*we are declaring typedef?*/
|
|
359 sp->s_attrib =| STYPEDEF;
|
|
360 if( instruct ) {
|
|
361 if( next(COLON) ) { /*handle bit field*/
|
|
362 sc = BFIELDCL;
|
|
363 i = cexpr();
|
|
364 j = (boffset<<8)|i;
|
|
365 if( redecf && sp->s_dp != j ) /* ??? */
|
|
366 goto redec;
|
|
367 sp->s_dp = j;
|
|
368 size = j = falign(type,i);
|
|
369 }
|
|
370 else
|
|
371 size = dsize(sp->s_type,sp->s_dp,sp->s_ssp) +
|
|
372 (j=salign(type,offset));
|
|
373 offset =+ j;
|
|
374 /* if( redecf && sp->s_offset != offset )
|
|
375 goto redec; */ /* [vlh] */
|
|
376 sp->s_offset = offset;
|
|
377 }
|
|
378 if( dtype == FUNCTION ) {
|
|
379 if( sc != AUTO && sc != EXTERNAL && sc != STATIC )
|
|
380 error("illegal function declaration");
|
|
381 if( sc != STATIC )
|
|
382 sc = EXTERNAL;
|
|
383 }
|
|
384 else if( sc == REGISTER ) {
|
|
385 if( !dtype ) {
|
|
386 if( !(dinfo[type]&DREG) ) { /* ignore reg specification */
|
|
387 /* error("illegal register specification"); */
|
|
388 sc = AUTO;
|
|
389 }
|
|
390 else if( !dregtab[ndregs] )
|
|
391 sc = AUTO;
|
|
392 else
|
|
393 sp->s_offset = dregtab[ndregs++];
|
|
394 }
|
|
395 else if( dtype != POINTER ) {
|
|
396 error("illegal register specification");
|
|
397 sc = AUTO; /*no more regs, make it auto*/
|
|
398 }
|
|
399 else if( !aregtab[naregs] )
|
|
400 sc = AUTO;
|
|
401 else
|
|
402 sp->s_offset = aregtab[naregs++];
|
|
403 }
|
|
404 if( sc == AUTO ) {
|
|
405 localsize =+ walign(dsize(sp->s_type,sp->s_dp,sp->s_ssp));
|
|
406 sp->s_offset = -localsize;
|
|
407 }
|
|
408 else if( sc == STATIC )
|
|
409 sp->s_offset = nextlabel++;
|
|
410 sp->s_sc = sc;
|
|
411 sp->s_attrib =| SDEFINED;
|
|
412 if(!infunc)
|
|
413 sp->s_attrib =| SGLOBAL;
|
|
1File: DECL.C Page 8
|
|
414 }
|
|
415 return(size);
|
|
416 }
|
|
417
|
|
418 /*
|
|
419 * doinit - do external definition initialization
|
|
420 * Handles following C syntax:
|
|
421 * initializer:
|
|
422 * = constant_expression
|
|
423 * = { initializer_list }
|
|
424 * = { initializer_list , }
|
|
425 * initializer_list:
|
|
426 * constant_expression
|
|
427 * initializer_list , initializer_list
|
|
428 * { initializer_list }
|
|
429 */
|
|
430 doinit(sp) /* returns number of elements init'ed*/
|
|
431 struct symbol *sp; /* pointer to symbol to init*/
|
|
432 {
|
|
433 register int type;
|
|
434 long isize, datasize, elsize;
|
|
435
|
|
436 type = sp->s_type;
|
|
437 datasize = dsize(type,sp->s_dp,sp->s_ssp);
|
|
438 if( peek(COMMA) || peek(SEMI) ) { /*no initialization*/
|
|
439 isize = walign(datasize);
|
|
440 if( sp->s_sc == EXTERNAL )
|
|
441 outcommon(sp->s_symbol,isize);
|
|
442 else {
|
|
443 outbss(); /*bss segment*/
|
|
444 outlab(sp->s_offset);
|
|
445 outresmem(isize);
|
|
446 outtext(); /*resume text segment*/
|
|
447 }
|
|
448 }
|
|
449 else {
|
|
450 next(ASSIGN); /*ignore '=' if there*/
|
|
451 if( type == LONG || pointer(type) )
|
|
452 outldata();
|
|
453 else if(type == DOUBLE || type == FLOAT) /*[vlh] 3.4*/
|
|
454 outfpdata();
|
|
455 else
|
|
456 outdata();
|
|
457 if( sp->s_sc == EXTERNAL )
|
|
458 outdlab(sp->s_symbol);
|
|
459 else
|
|
460 outlab(sp->s_offset);
|
|
461 isize = initlist(sp->s_type,sp->s_dp,sp->s_ssp);
|
|
462 if( isize < datasize ) {
|
|
463 outresmem(datasize-isize);
|
|
464 isize = datasize;
|
|
465 }
|
|
466 if( walign(isize) != isize )
|
|
467 outpad();
|
|
468 if( isize > datasize ) {
|
|
469 if( array(sp->s_type) ) {
|
|
470 for( type = sp->s_type; array(type); type = delsp(type) )
|
|
471 ;
|
|
472 dtab[sp->s_dp] = isize / dsize(type,sp->s_dp,sp->s_ssp);
|
|
1File: DECL.C Page 9
|
|
473 }
|
|
474 else
|
|
475 error("too many initializers");
|
|
476 }
|
|
477 if( sp->s_sc == STATIC )
|
|
478 outtext();
|
|
479 }
|
|
480 }
|
|
481
|
|
482 /*
|
|
483 * initlist - handles initializer lists
|
|
484 * This handles multi-level braces, and a character pointer pointing
|
|
485 * to a string. Most of the work is in keeping track of how many
|
|
486 * bytes are left on the current "row", and outputting padding if
|
|
487 * necessary.
|
|
488 */
|
|
489 long
|
|
490 initlist(type,dp,sp) /* returns size of initializers in*/
|
|
491 /* bytes*/
|
|
492 int type; /* type of data*/
|
|
493 int dp; /* dimension pointer*/
|
|
494 int sp; /* structure pointer*/
|
|
495 {
|
|
496 register int nrows;
|
|
497 long datasize, i, elsize, nbleft, nbout; /* [vlh] 3.4 int=>long */
|
|
498 register int onetype;
|
|
499
|
|
500 for( onetype = type; array(onetype); onetype = delsp(onetype) )
|
|
501 ;
|
|
502 nbout = 0;
|
|
503 datasize = dsize(type,dp,sp);
|
|
504 nbleft = 0; /*keep track of no. of bytes left*/
|
|
505 if( type == (ARRAY|CHAR) && next(STRING) ) {
|
|
506 nbout = cstrsize;
|
|
507 outstr();
|
|
508 if( datasize > nbout )
|
|
509 nbleft = datasize - nbout;
|
|
510 }
|
|
511 else if( array(type) || (btype(type)==STRUCT && notpointer(type)) ) {
|
|
512 elsize = datasize / dsize(delsp(type),dp+1,sp);
|
|
513 elsize = datasize / elsize;
|
|
514 if(!next(LCURBR))
|
|
515 error("missing { in initialization");
|
|
516 if( type == (ARRAY|CHAR) && next(STRING) ) {
|
|
517 nbout = cstrsize;
|
|
518 outstr();
|
|
519 if( datasize > nbout )
|
|
520 nbleft = datasize - nbout;
|
|
521 }
|
|
522 else {
|
|
523 do { /*in current row.*/
|
|
524 if( peek(SEMI) || peek(EOF) )
|
|
525 break;
|
|
526 if( peek(LCURBR) ) { /*recurse down one level?*/
|
|
527 if( nbleft ) {
|
|
528 outresmem(nbleft); /*pad rest of current row*/
|
|
529 nbout =+ nbleft;
|
|
530 nbleft = 0;
|
|
531 }
|
|
1File: DECL.C Page 10
|
|
532 i = initlist(delsp(type),dp+1,sp);
|
|
533 if( i > elsize )
|
|
534 error("initializer list too long");
|
|
535 else if( i < elsize )
|
|
536 outresmem(elsize-i);
|
|
537 nbout =+ elsize;
|
|
538 }
|
|
539 else if( peek(RCURBR) )
|
|
540 break;
|
|
541 else {
|
|
542 i = oneinit(onetype);
|
|
543 nbout =+ i;
|
|
544 if(!nbleft)
|
|
545 nbleft = elsize;
|
|
546 if( i > nbleft )
|
|
547 error("initializer alignment");
|
|
548 nbleft = (i >= nbleft) ? 0 : nbleft - i;
|
|
549 }
|
|
550 } while( next(COMMA) );
|
|
551 }
|
|
552 if(!next(RCURBR))
|
|
553 synerr("missing }");
|
|
554 }
|
|
555 else {
|
|
556 i = next(LCURBR); /*pull of optional {*/
|
|
557 nbout = oneinit(onetype);
|
|
558 if( i && !next(RCURBR) )
|
|
559 synerr("missing }");
|
|
560 }
|
|
561 if( nbleft ) { /*pad current row*/
|
|
562 outresmem(nbleft);
|
|
563 nbout =+ nbleft;
|
|
564 }
|
|
565 return(nbout);
|
|
566 }
|
|
567
|
|
568 /*
|
|
569 * oneinit - get one initializer expression or constant
|
|
570 * This checks the type of the data item expected against the
|
|
571 * type obtained from expr. Note that there is no attempt to
|
|
572 * match structure initializations against the elements of the
|
|
573 * structure, hence, anything goes in a structure.
|
|
574 */
|
|
575 oneinit(type) /* returns size of initializer*/
|
|
576 int type; /* type of initializer*/
|
|
577 {
|
|
578 register int op, value;
|
|
579 register struct tnode *tp;
|
|
580
|
|
581 commastop++;
|
|
582 tp = expr();
|
|
583 commastop--;
|
|
584 op = tp->t_op;
|
|
585 value = tp->t_value;
|
|
586 switch( alltype(type) ) {
|
|
587
|
|
588 case CHAR:
|
|
589 case ARRAY|CHAR:
|
|
590 if( op != CINT )
|
|
1File: DECL.C Page 11
|
|
591 break;
|
|
592 outc(CHAR,value);
|
|
593 return(1);
|
|
594
|
|
595 case INT:
|
|
596 case ARRAY|INT:
|
|
597 case UNSIGNED:
|
|
598 case ARRAY|UNSIGNED:
|
|
599 if( op == CLONG || op == ADDR )
|
|
600 break;
|
|
601 if( op == CINT )
|
|
602 outc(INT,value);
|
|
603 else
|
|
604 outinit(tp,inittype);
|
|
605 return(2);
|
|
606
|
|
607 case LONG:
|
|
608 case ARRAY|LONG:
|
|
609 case POINTER|CHAR:
|
|
610 case POINTER|INT:
|
|
611 case POINTER|LONG:
|
|
612 case POINTER|STRUCT:
|
|
613 case POINTER|UNSIGNED:
|
|
614 if( op == CINT ) {
|
|
615 clvalue = value; /*[vlh] fix ??? MC ??? */
|
|
616 outlong(clvalue);
|
|
617 }
|
|
618 else if( op == CLONG )
|
|
619 outlong(clvalue);
|
|
620 else
|
|
621 outinit(tp,inittype);
|
|
622 return(4);
|
|
623
|
|
624 case DOUBLE: /* [vlh] 3.4 */
|
|
625 case FLOAT:
|
|
626 outfp(clvalue);
|
|
627 return(4);
|
|
628
|
|
629 case STRUCT:
|
|
630 case ARRAY|STRUCT:
|
|
631 if( op == CINT ) {
|
|
632 if( xflag ) {
|
|
633 clvalue = value;
|
|
634 outlong(clvalue);
|
|
635 return(4);
|
|
636 }
|
|
637 outc(INT,value);
|
|
638 return(2);
|
|
639 }
|
|
640 if( op == CLONG ) {
|
|
641 outlong(clvalue);
|
|
642 return(4);
|
|
643 }
|
|
644 outinit(tp,inittype);
|
|
645 if (xflag || op==ADDR) return(4);
|
|
646 if ((op=tp->t_right->t_op)==ADDR || op==CLONG) return(4); /*[vlh]*/
|
|
647 if ((op=tp->t_left->t_op)==ADDR || op==CLONG) return(4); /*[vlh]*/
|
|
648 return(2);
|
|
649 }
|
|
1File: DECL.C Page 12
|
|
650 error("invalid initializer");
|
|
651 return(0);
|
|
652 }
|
|
653
|
|
654 /*
|
|
655 * funcbody - do function body declaration
|
|
656 * Basically handles function after we have scanned the parameter
|
|
657 * list, which is now set up in fargs array. We now proceed to
|
|
658 * look for any declarations for the function arguments, then the
|
|
659 * function declaration list, followed by the function statement list.
|
|
660 * The C syntax is:
|
|
661 * function_body:
|
|
662 * type_decl_list function_statement
|
|
663 * function_statement:
|
|
664 * { declaration_list statement_list }
|
|
665 */
|
|
666 funcbody(fsp)
|
|
667 struct symbol *fsp;
|
|
668 {
|
|
669 register int olddp;
|
|
670 register struct symbol *sp;
|
|
671 register struct farg *fp;
|
|
672 register int offset, toff;
|
|
673
|
|
674 infunc++;
|
|
675 sp = fsp;
|
|
676 opap = exprp;
|
|
677 frp = snalloc(delsp(sp->s_type),sp->s_sc,sp->s_type,sp->s_dp,
|
|
678 sp->s_ssp);
|
|
679 exprp = opap;
|
|
680 outtext();
|
|
681 outflab(sp->s_symbol);
|
|
682 olddp = cdp;
|
|
683 dlist(PDECLIST);
|
|
684 rlabel = nextlabel++;
|
|
685 if(!next(LCURBR))
|
|
686 synerr("function body syntax");
|
|
687 else {
|
|
688 localsize = 0; /*end of first auto offset from l.e.p.*/
|
|
689 offset = 8; /*first arg offset from l.e.p.*/
|
|
690 for( fp = &fargtab[0]; sp = fp->f_sp; fp++ ) {
|
|
691 toff = offset;
|
|
692 if( sp->s_type == CHAR ) /*char argument*/
|
|
693 toff++; /*offset of lower byte in word*/
|
|
694 if( sp->s_sc == REGISTER )
|
|
695 fp->f_offset = toff;
|
|
696 else {
|
|
697 fp->f_offset = 0; /*really is auto arg*/
|
|
698 sp->s_offset = toff;
|
|
699 sp->s_sc = AUTO;
|
|
700 }
|
|
701 if( array(sp->s_type) ) { /*change array ref to pointer*/
|
|
702 sp->s_type = addsp(delsp(sp->s_type),POINTER);
|
|
703 sp->s_dp++;
|
|
704 }
|
|
705 offset =+ walign(dsize(sp->s_type,sp->s_dp,sp->s_ssp));
|
|
706 }
|
|
707 dlist(0);
|
|
708 chksyms();
|
|
1File: DECL.C Page 13
|
|
709 outbentry(localsize,ndregs,naregs);
|
|
710 copyargs(); /*copy args to registers where required*/
|
|
711 while(!next(RCURBR)) {
|
|
712 if( next(EOF) ) {
|
|
713 error("{ not matched by }");
|
|
714 break;
|
|
715 }
|
|
716 stmt();
|
|
717 }
|
|
718 }
|
|
719 outlab(rlabel);
|
|
720 outbexit(ndregs,naregs);
|
|
721 cdp = olddp;
|
|
722 infunc--;
|
|
723 freesyms();
|
|
724 }
|
|
725
|
|
726 /*
|
|
727 * copyargs - copy args to register where required
|
|
728 * fargtab has been set so that args declared to be registers have a
|
|
729 * non-zero offset value and the register number is in the symbol
|
|
730 * table pointed to by symbol.
|
|
731 */
|
|
732 copyargs() /* returns - none*/
|
|
733 {
|
|
734 register struct symbol *sp;
|
|
735 register struct farg *fp;
|
|
736
|
|
737 for( fp = &fargtab[0]; sp = fp->f_sp; fp++ ) {
|
|
738 if( fp->f_offset ) /*was declared register*/
|
|
739 outassign(snalloc(sp->s_type,sp->s_sc,sp->s_offset,0,0),
|
|
740 snalloc(sp->s_type,AUTO,fp->f_offset,0,0));
|
|
741 }
|
|
742 }
|
|
743
|
|
744 /*
|
|
745 * dlist - declaration list
|
|
746 * Handles declaration lists in the following places:
|
|
747 * function parameter list declarations, structure or union member
|
|
748 * declarations and local declarations in functions.
|
|
749 */
|
|
750 long
|
|
751 dlist(defsc) /* returns length of declarators*/
|
|
752 int defsc; /* default storage class*/
|
|
753 {
|
|
754 register int offset;
|
|
755 register struct symbol *sp;
|
|
756 register long i, ddsize;
|
|
757 long size; /* [vlh] 3.4 int => long */
|
|
758 int type, sc, isize;
|
|
759
|
|
760 offset = 0; ddsize = 0L;
|
|
761 do {
|
|
762 sc = defsc;
|
|
763 type = INT;
|
|
764 if( !gettype(&sc,&type,&size) )
|
|
765 break;
|
|
766 do {
|
|
767 i = dodecl(sc,type,offset,size);
|
|
1File: DECL.C Page 14
|
|
768 if( defsc != UNELCL ) {
|
|
769 isize = i;
|
|
770 offset =+ isize;
|
|
771 ddsize =+ i;
|
|
772 }
|
|
773 else if( i > ddsize )
|
|
774 ddsize = i;
|
|
775 if( sc == STATIC && dsp && !stypedef(dsp) )
|
|
776 doinit(dsp); /*process any initializer*/
|
|
777 dsp = 0;
|
|
778 } while ( next(COMMA) );
|
|
779 if(!next(SEMI)) {
|
|
780 synerr("declaration syntax");
|
|
781 break;
|
|
782 }
|
|
783 } while( 1 );
|
|
784 isize = ddsize;
|
|
785 ddsize =+ salign(INT,isize);
|
|
786 return(ddsize);
|
|
787 }
|
|
788
|
|
789 /*
|
|
790 * declarator - get one declarator
|
|
791 * Basically uses getdecl, which returns the declaration types
|
|
792 * reversed in the type word.
|
|
793 */
|
|
794 declarator(castflg) /* returns type or -1*/
|
|
795 int castflg;
|
|
796 {
|
|
797 register int type, t;
|
|
798
|
|
799 dsp = 0;
|
|
800 if( (type=getdecl(castflg)) >= 0 )
|
|
801 return( revsp(type) );
|
|
802 return(type);
|
|
803 }
|
|
804
|
|
805 /*
|
|
806 * getdecl - get one declarator, handling *, (), etc.
|
|
807 * The significance of the value returned by declarator is: the
|
|
808 * least significant two bits represent the values (POINTER,FUNCTION,
|
|
809 * ARRAY), these values are repeated through the word. For example,
|
|
810 * the declarations result in the following values for declarator:
|
|
811 * *x() => (POINTER,FUNCTION)
|
|
812 * (*x)() => (FUNCTION,POINTER)
|
|
813 * *(*x)() => (POINTER,FUNCTION,POINTER)
|
|
814 * The following C syntax is handled here:
|
|
815 * function_declarator:
|
|
816 * declarator ( parameter_list )
|
|
817 * declarator:
|
|
818 * identifier
|
|
819 * ( declarator )
|
|
820 * * declarator
|
|
821 * declarator [ constant-expression ]
|
|
822 */
|
|
823 getdecl(castflg) /* returns special type of declarator*/
|
|
824 int castflg; /* casting flag, 1=>allow no declarator*/
|
|
825 {
|
|
826 register int type, i, value, sdp;
|
|
1File: DECL.C Page 15
|
|
827 register struct symbol *sp, *tsp;
|
|
828 register struct farg *fp;
|
|
829 register char *p;
|
|
830 long lvalue;
|
|
831
|
|
832 type = 0;
|
|
833 if( next(LPAREN) ) { /*( declarator ) ...*/
|
|
834 type = getdecl(castflg);
|
|
835 if(!next(RPAREN))
|
|
836 goto baddec;
|
|
837 }
|
|
838 if( next(MULT) )
|
|
839 return(addsp(getdecl(castflg),POINTER));
|
|
840 sdp = cdp;
|
|
841 if( next(SYMBOL) ) {
|
|
842 sp = dsp = csp;
|
|
843 type = 0;
|
|
844 sp->s_dp = sdp;
|
|
845 }
|
|
846 while( 1 ) {
|
|
847 if( next(LPAREN) ) { /*declarator ( ... )*/
|
|
848 if(!infunc) {
|
|
849 ndregs = naregs = 0;
|
|
850 for( fp = &fargtab[0]; next(SYMBOL); ) {
|
|
851 p = csp;
|
|
852 if( p->s_attrib & SDEFINED )
|
|
853 error("redeclaration: %.8s",p->s_symbol);
|
|
854 else if( fp >= &fargtab[NFARGS-1] ) {
|
|
855 synerr("too many params");
|
|
856 break;
|
|
857 }
|
|
858 else {
|
|
859 p->s_attrib =| SDEFINED;
|
|
860 p->s_sc = PARMLIST;
|
|
861 p->s_type = INT; /*default to int*/
|
|
862 fp->f_sp = p;
|
|
863 fp++;
|
|
864 }
|
|
865 if(!next(COMMA))
|
|
866 break;
|
|
867 }
|
|
868 fp->f_sp = 0;
|
|
869 }
|
|
870 if(!next(RPAREN))
|
|
871 break;
|
|
872 type = addsp(type,FUNCTION);
|
|
873 continue;
|
|
874 }
|
|
875 if( next(LBRACK) ) { /*declarator [ cexpr ]*/
|
|
876 if( next(RBRACK) )
|
|
877 dalloc(1L);
|
|
878 else {
|
|
879 tsp = dsp; /* [vlh] 3.4 save in case of reset */
|
|
880 value = cexpr(); /* recurses on sizeof.... resets dsp */
|
|
881 dsp = tsp; /* [vlh] 3.4 */
|
|
882 lvalue = value; /* [vlh] 3.4 */
|
|
883 for( i = sdp; i < cdp; )
|
|
884 dtab[i++] =* lvalue;
|
|
885 dalloc(lvalue);
|
|
1File: DECL.C Page 16
|
|
886 if( !next(RBRACK) )
|
|
887 break;
|
|
888 }
|
|
889 type = addsp(type,ARRAY);
|
|
890 continue;
|
|
891 }
|
|
892 if( castflg || dsp )
|
|
893 return(type);
|
|
894 break;
|
|
895 }
|
|
896 baddec:
|
|
897 synerr("invalid declarator");
|
|
898 return(-1);
|
|
899 }
|
|
900
|
|
901 /* dalloc - dimension table allocation*/
|
|
902 /* Allocates an entry in the dimension table.*/
|
|
903 dalloc(dimsize) /* returns ptr to dimension allocated*/
|
|
904 long dimsize; /* dimension size [vlh] 3.4 i=>l*/
|
|
905 {
|
|
906 register int i;
|
|
907
|
|
908 if( (i=cdp++) >= DSIZE-1 )
|
|
909 ferror("dimension table overflow");
|
|
910 dtab[i] = dimsize;
|
|
911 return(i);
|
|
912 }
|
|
913
|
|
914 /* addsp - add special type to special type info*/
|
|
915 /* Takes given special type and adds it into the special type field.*/
|
|
916 addsp(type,nsptype) /* returns resulting type*/
|
|
917 int type; /* old type field*/
|
|
918 int nsptype; /* special type to be added*/
|
|
919 {
|
|
920 register int dtype;
|
|
921
|
|
922 dtype = btype(type);
|
|
923 type =& (~TYPE);
|
|
924 return( (type<<SUTYPLEN) | suptype(nsptype) | dtype );
|
|
925 }
|
|
926
|
|
927 /* delsp - delete one special type info field from special type info*/
|
|
928 /* Takes given special type field and deletes least sign.*/
|
|
929 delsp(type) /* returns resulting type*/
|
|
930 int type; /* old special type*/
|
|
931 {
|
|
932 register int dtype;
|
|
933
|
|
934 dtype = btype(type);
|
|
935 type =& (~(ALLTYPE));
|
|
936 return( (type>>SUTYPLEN) | dtype );
|
|
937 }
|
|
938
|
|
939 /*
|
|
940 * revsp - reverse special type info
|
|
941 * This allows for the processing of the super-type info in
|
|
942 * the reverse order, which is necessary for initializations.
|
|
943 */
|
|
944 revsp(type) /* returns reversed type info*/
|
|
1File: DECL.C Page 17
|
|
945 int type; /* type to reverse*/
|
|
946 {
|
|
947 register int t;
|
|
948
|
|
949 for( t = btype(type); suptype(type) != 0; type = delsp(type) )
|
|
950 t = addsp(t,type);
|
|
951 return(t);
|
|
952 }
|
|
953
|
|
954 /* falign - handle bit field alignments*/
|
|
955 falign(type,flen) /* returns number of bytes padded*/
|
|
956 int type; /* data type*/
|
|
957 int flen; /* field length*/
|
|
958 {
|
|
959 register int off;
|
|
960
|
|
961 off = 0;
|
|
962 if( flen <= 0 ) {
|
|
963 error("invalid field size");
|
|
964 flen = 0;
|
|
965 }
|
|
966 switch( type ) {
|
|
967
|
|
968 case INT:
|
|
969 case UNSIGNED:
|
|
970 if( flen > BITSPWORD )
|
|
971 error("field overflows word");
|
|
972 if( flen + boffset > BITSPWORD )
|
|
973 off = CHRSPWORD;
|
|
974 break;
|
|
975
|
|
976 case CHAR:
|
|
977 if( flen > BITSPCHAR )
|
|
978 error("field overflows byte");
|
|
979 if( flen + boffset > BITSPCHAR )
|
|
980 off = 1;
|
|
981 break;
|
|
982
|
|
983 default:
|
|
984 error("invalid field type description");
|
|
985 return(0);
|
|
986
|
|
987 }
|
|
988 if( off )
|
|
989 boffset = 0;
|
|
990 boffset =+ flen;
|
|
991 return(off);
|
|
992 }
|
|
993
|
|
994 /* salign - structure alignment*/
|
|
995 salign(type,offset) /* returns bytes of padding*/
|
|
996 int type; /* data type to align*/
|
|
997 int offset; /* current structure offset*/
|
|
998 {
|
|
999 register int off;
|
|
1000
|
|
1001 off = offset;
|
|
1002 if( boffset ) { /*remaining bit fields, flush 'em*/
|
|
1003 off =+ (boffset+(BITSPCHAR-1))/BITSPCHAR;
|
|
1File: DECL.C Page 18
|
|
1004 boffset = 0;
|
|
1005 }
|
|
1006 while( array(type) ) /*get base type*/
|
|
1007 type = delsp(type);
|
|
1008 if( type != CHAR ) /*need word boundary*/
|
|
1009 off = walign(off);
|
|
1010 return( off - offset );
|
|
1011 }
|
|
1012
|
|
1013 /* dsize - returns size of data object in bytes*/
|
|
1014 long /* [vlh] 3.4 */
|
|
1015 dsize(type,dp,sp) /* returns number of bytes*/
|
|
1016 int type; /* type of node*/
|
|
1017 int dp; /* dimension pointer*/
|
|
1018 int sp; /* size pointer if structure*/
|
|
1019 {
|
|
1020 register long nel, size;
|
|
1021
|
|
1022 nel = 1;
|
|
1023 for( ; array(type); type = delsp(type) )
|
|
1024 nel = dtab[dp];
|
|
1025 if( function(type) )
|
|
1026 return(0);
|
|
1027 size = (pointer(type)) ? PTRSIZE : (type == STRUCT) ?
|
|
1028 dtab[sp] : dinfo[type]&DTSIZE;
|
|
1029 if(!size)
|
|
1030 error("invalid data type");
|
|
1031 return( size * nel );
|
|
1032 }
|
|
1033
|
|
1034 /*
|
|
1035 * addtdtype - add typedef info into declarator
|
|
1036 * here we very carefully add in the dimensions for an array typedef
|
|
1037 * declaration. Note that declarator has already allocated the
|
|
1038 * declarator-specific dimensions, now we allocate the typedef
|
|
1039 * dimensions and adjust the size of the declarator's dimensions.
|
|
1040 * Note that this must be done before the dalloc for the structure,
|
|
1041 * otherwise we would mix up array and structure sizes.
|
|
1042 */
|
|
1043 addtdtype(tddp,type,dp,ssp) /* returns type*/
|
|
1044 struct symbol *tddp;
|
|
1045 int type;
|
|
1046 int dp;
|
|
1047 int *ssp;
|
|
1048 {
|
|
1049 register int ntype, t, i, tdf;
|
|
1050
|
|
1051 for( tdf = 0, t = tddp->s_type; suptype(t); t = delsp(t) )
|
|
1052 if( array(t) ) {
|
|
1053 tdf++;
|
|
1054 break;
|
|
1055 }
|
|
1056 ntype = 0;
|
|
1057 for( t = type, i = dp; suptype(t); t = delsp(t) ) {
|
|
1058 ntype = addsp(ntype,t);
|
|
1059 if( tdf && array(t) )
|
|
1060 dtab[i++] =* dtab[tddp->s_dp];
|
|
1061 }
|
|
1062 for( t = tddp->s_type, i = tddp->s_dp; suptype(t); t = delsp(t) )
|
|
1File: DECL.C Page 19
|
|
1063 if( array(t) )
|
|
1064 dalloc(dtab[i++]);
|
|
1065 for( t = tddp->s_type; suptype(ntype); ntype = delsp(ntype) )
|
|
1066 t = addsp(t,ntype);
|
|
1067 if( (ntype=btype(t)) == STRUCT )
|
|
1068 *ssp = tddp->s_ssp;
|
|
1069 else if( ntype == FRSTRUCT )
|
|
1070 *ssp = frstp;
|
|
1071 return(t);
|
|
1072 }
|