Move the sources to trunk
[opencv] / apps / Hawk / CVEiCL / EiC / src / cdecl.c
1 /* cdecl.c
2  *
3  *      (C) Copyright Apr 15 1995, Edmond J. Breen.
4  *                 ALL RIGHTS RESERVED.
5  * This code may be copied for personal, non-profit use only.
6  *
7  */
8
9 /* Modified by Intel OpenCV team. Added lines 528-531 in order to prevent 
10    the parser exceptions throwing in specific cases. No guarantee that this 
11    is the fix for all cases. */
12
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "MachSet.h"
19 #include "global.h"
20 #include "lexer.h"
21 #include "typemod.h"
22 #include "func.h"
23 #include "xalloc.h"
24 #include "cdecl.h"
25 #include "preproc.h"
26 #include "error.h"
27 #include "typesets.h"
28 #include "parser.h"
29 #include "symbol.h"
30
31 int EiC_work_tab;
32 static int LSP, RESET = 0;
33 int EiC_RETURNON = 0;
34 int EiC_INFUNC = 0;
35 static int ABSDECL = 0;     /* constant for abstract declorator */
36 static int INPARMLIST = 0;
37 static token_t * INSTUN = 0;
38 static type_expr *PRAMHANDLE;
39 token_t *EiC_RETURNEXPR;
40
41 /* TODO: external functions that need to be declared in a header somewhere */
42 void EiC_SaveGlobalString(ptr_t *s);
43 void EiC_reset_env_pointers(token_t *, int bp);
44
45 /** PROTOTYPES from cdecl.c **/
46 static int isredec(token_t * e1);
47 static void establish_id(token_t * e1);
48 static void new_var(token_t * e1);
49 static void addreturn(token_t *,code_t * c);
50 static void f_ext_decl(token_t * e1);
51 static void ff_ext_decl(token_t * e1);
52 static void fff_ext_decl(token_t * e1);
53 static void semi_colon(token_t * e1);
54 static void decl_spec(token_t * e1);
55 static void specifier(token_t *e1, int t,int *sclass);
56 static void init_decl_list(token_t * e1);
57 static void init_decl(token_t * e1, int t);
58 static void initialiser(token_t * e1);
59 static void decl(token_t * e1, int t);
60 static type_expr * pointer(void);
61 static void dir_decl(token_t * e1, int t);
62 static void f_dir_decl(token_t * e1);
63 static void ff_dir_decl(token_t * e1);
64 static void parm_type_list(func_t * f);
65 static void f_parm_type_list(func_t * f);
66 static void parm_decl(token_t * e1);
67 static void enum_spec(token_t * e1);
68 static void f_enum_spec(token_t * e1);
69 static void enum_list(token_t * e1);
70 static void array_decl(token_t * e1);
71 static void st_un_spec(token_t * e1, int t);
72 static void f_st_un_spec(token_t * e1);
73 static void s_decl_list(token_t * e1);
74 static void st_decl(token_t * e1, int t);
75 static void spec_qual_list(token_t * e1, int t);
76 static void r_spec_qual_list(token_t * e1);
77 static void addst_un_tag(symentry_t *sym);
78 static void addst_un_mem(token_t * e1, token_t * e2);
79 static void spec_declor_list(token_t * e1, token_t * e2);
80 static void st_declor(token_t * e1, int t);
81 static void f_st_declor();
82 static void abs_decl(token_t * e1, int t);
83 static void f_abs_decl(token_t * e1);
84 static void dir_abs_decl(token_t * e1, int t);
85 static void f1_dir_abs(token_t * e1);
86 static void EiC_f2_dir_abs(token_t * e1);
87
88
89 /* RoundUp returns x rounded to the next multiple
90  * of n, which must be a power of two.
91  */
92 #define RoundUp(x,n) (((x)+((n)-1))&(~((n)-1)))
93 #define init_ident(e,t)  (e)->Val = token->Val; (e)->Tab = (t)
94
95 static int isredec(token_t * e1)
96 {
97     /* test for re declaration. */
98     return EiC_sametypes(e1->Type, e1->Val.sym->type);
99 }
100
101 #if 0
102
103 #define setBoundaryLimits(x)
104
105 #else
106 static void setBoundaryLimits(token_t *e1)
107 {
108     int t = EiC_gettype(e1->Type);
109     if(e1->Sclass == c_typedef) /* watch out for typedefs */
110         return;
111     if((!EiC_INFUNC || EiC_GI(e1) == 0) && t > t_pointer &&  
112        !(t == t_func || t == t_funcdec || t == t_builtin)) {
113         ptr_t *p;
114         int s = EiC_get_sizeof(e1->Type);
115         
116         if(!isconst(e1->Type)) 
117             p = &EiC_ENV->AR[e1->Sym->val.ival].v.p;
118         else 
119             p  = &e1->Sym->val.p;
120         
121         p->sp = p->p;
122         p->ep = (char*)p->p + s;
123             
124     }
125     /* automatic aggregate
126      * types are done on the fly.
127      */
128
129 }
130 #endif
131
132 static void handle_address_operator(token_t *e1)
133 {
134   extern int TREFON;
135   int h = TREFON;
136   TREFON = 1;
137   
138   EiC_exchtype(t_pointer,e1->Type);
139   initialiser(e1);
140   EiC_exchtype(t_ref,e1->Type);
141
142   TREFON = h;
143
144 }
145
146    
147 static void cast_t_enum(token_t *e1)
148 {
149   /* enumeration types into ints */
150   e1->Type = EiC_addtype(t_int, EiC_freetype(e1->Type));
151   EiC_setAsBaseType(e1->Type);
152 }
153
154
155 static int checklevel(token_t *e1,symentry_t * sym, int level)
156 {
157     /*
158      * Checks to see if there is a true difference between
159      * the current scope and the declaration scope.
160      */
161     
162     if(sym->level != level) {
163         int t = EiC_gettype(e1->Type);
164         if((t == t_func || t == t_funcdec) && !INPARMLIST) {
165             return 0;
166         } else 
167             return 1;
168     } else
169 #if 0    
170         if(level == 1 && sym->id != CurrentFileName()) {
171             if (e1->Sclass & c_static)
172                 return 1;
173         }
174 #endif
175     return 0;
176 }
177
178 static void setscope(symentry_t * sym,int level, int t)
179 {
180     void EiC_UpdateSymPos(symentry_t * sym);
181     if((t == t_func || t == t_funcdec) && !INPARMLIST) {
182         sym->level = 1;
183     } else if(sym->sclass == c_extern)
184         sym->level = 1;
185     else
186         sym->level = level;
187     if(sym->level < level ||
188        (sym->next && sym->next->level > sym->level))
189         EiC_UpdateSymPos(sym);
190 }
191
192 static void freeArray(token_t *e1)
193 {
194     if(EiC_get_sizeof(e1->Val.sym->type))
195         xfree(EiC_ENV->AR[e1->Val.sym->val.ival].v.p.p);
196     EiC_ENV->AR[e1->Val.sym->val.ival].v.p.p = NULL;
197 }
198
199 static void check_decl(token_t * e1)
200 {
201     int t;
202     type_expr *ty = e1->Type;
203     for(;ty;ty=nextType(ty))
204         if((t=EiC_gettype(ty)) == t_funcdec || t == t_func) {
205             t = EiC_gettype(nextType(ty));
206             if(t == t_array || t == t_funcdec)
207                 EiC_error("Illegal return type for %s",
208                       e1->Val.sym->id);
209         }
210 }
211
212 static void doBuiltin(token_t * e1)
213 {
214     void EiC_UpdateEntry(symentry_t * sym);
215     if(token->Tok == ';') { /* must be a prototype */
216         EiC_UpdateEntry(e1->Val.sym);
217         if(nextType(e1->Val.sym->type)) {
218             EiC_warningerror("2nd prototype for builtin -> %s",
219                          e1->Val.sym->id);
220         }
221         EiC_freetype(e1->Val.sym->type);
222         EiC_exchtype(t_builtin,e1->Type);
223         e1->Val.sym->type = e1->Type;
224         e1->Sym = e1->Val.sym;
225     }else
226         EiC_error("Illegal redefinition of builtin function %s",
227               e1->Val.sym->id);
228 }
229
230 static void showRedec(token_t *e1)
231 {
232    char *  EiC_getClashedfname(char nspace,char *id);
233    extern int Pclash;
234    char *fn;
235
236    if(Pclash)
237        fn = EiC_getClashedfname(EiC_work_tab,e1->Val.sym->id);
238    else
239        fn = e1->Val.sym->fname;
240    
241    EiC_error(" Redeclaration of parameter `%s'\n"
242              "Previously declared in: %s",e1->Val.sym->id,fn);
243
244
245    /* generate a dummy entry */
246    e1->Val.sym = EiC_insertLUT(e1->Tab,
247                            e1->Val.sym->id, ID);
248 }
249
250 static void establish_id(token_t * e1)
251 {
252     /* e1->Val.sym->type is the previous or
253            stored type
254        e1->Type is the new type 
255        */
256
257     extern int Pclash;
258     int level,t;
259     void EiC_UpdateEntry(symentry_t * sym);
260     
261     if ((t=EiC_gettype(e1->Val.sym->type)) == ID) {
262         /* variable not declared  previously,
263          * but check for possible clashes with
264          * previously declared static variables
265          */
266
267         if(Pclash && !(e1->Sclass & c_static) && !(EiC_INFUNC || INPARMLIST || INSTUN))
268             showRedec(e1);
269
270     } else if(e1->Sclass != c_extern && 
271             ( checklevel(e1,e1->Val.sym,EiC_S_LEVEL) 
272             || e1->Tab != e1->Val.sym->nspace))
273         e1->Val.sym = EiC_insertLUT(e1->Tab, e1->Val.sym->id, ID);
274     else if (isredec(e1)) {
275         if(EiC_INFUNC && EiC_S_LEVEL == 2 && e1->Val.sym->val.ival < 0)
276             showRedec(e1);
277         /* catch declaration after definition */
278         if(t == t_func) {
279             /* Swap  Parmameter Lists */
280
281             if(token->Tok == '{') { /* is definition */
282                 if(e1->Val.sym->fname == CurrentFileName()) {
283                     func_t *f2 = (func_t *)EiC_getInf(e1->Type);
284                     if(EiC_hasPrototype(f2)) 
285                         EiC_swapFPLists(EiC_getInf(e1->Val.sym->type),f2);
286                     EiC_UpdateEntry(e1->Val.sym);
287                 } else
288                     showRedec(e1);
289             }
290             
291             EiC_freetype(e1->Type);
292             e1->Type = e1->Val.sym->type ;
293             e1->Sym = e1->Val.sym;
294             return;
295             
296         } else if(t == t_builtin) {
297             doBuiltin(e1);
298             return;
299         } else if(CurrentFileName() != e1->Val.sym->fname &&
300                   (e1->Sclass & c_static)) {
301             e1->Val.sym = EiC_insertLUT(e1->Tab, e1->Val.sym->id, ID);
302         } else if(CurrentFileName() != e1->Val.sym->fname &&
303                   e1->Sclass != c_extern &&
304                   e1->Val.sym->sclass != c_extern &&
305                   t != t_funcdec) {
306             showRedec(e1);
307         } else {
308             EiC_UpdateEntry(e1->Val.sym);
309             if((t=EiC_gettype(e1->Type)) == t_array) {
310                 if(e1->Sclass != c_extern)
311                     freeArray(e1);
312             } else if(t == t_struct || (t == t_union)) {
313                 /* use original copy */
314                 EiC_freetype(e1->Type);
315                 e1->Type = e1->Val.sym->type ;
316             } if(t == t_funcdec) {
317                 func_t *f1,  *f2;
318                 f1 = EiC_getInf(e1->Type);
319                 f2 = EiC_getInf(e1->Val.sym->type);
320                 setFcallBack(f1,getFcallBack(f2));
321                 setFcallBack(f2,NULL);
322             }
323
324                 
325             e1->Sym = e1->Val.sym;
326             return;
327         }
328     } else if(t == t_builtin) {
329         doBuiltin(e1);
330         return;
331     } else if(t == t_ref) {
332         if((e1->Sclass & c_extern) && 
333            EiC_sametypes(e1->Type,nextType(e1->Val.sym->type))) {
334             e1->Sym = e1->Val.sym;
335             EiC_freetype(e1->Type);
336             e1->Type = e1->Sym->type;
337             return;
338         } else /* error */
339             showRedec(e1);
340     } else {
341         if(e1->Val.sym->level == EiC_S_LEVEL &&
342            !(e1->Sclass & c_static && 
343            e1->Val.sym->fname != CurrentFileName()))        
344             showRedec(e1);
345         else
346             /* generate space in lookup table */
347             e1->Val.sym = EiC_insertLUT(e1->Tab, e1->Val.sym->id, ID);
348     }
349     e1->Val.sym->sclass = e1->Sclass;
350     setscope(e1->Val.sym,EiC_S_LEVEL,EiC_gettype(e1->Type));
351     e1->Val.sym->nspace = e1->Tab;
352     e1->Sym = e1->Val.sym;
353     if (e1->Sclass == c_static) {
354         level = 1;
355         if(EiC_S_LEVEL == 1) {
356             /* mark as private */
357             e1->Sym->sclass |= c_private;
358         }
359             
360     } else
361         level = e1->Val.sym->level; /*EiC_S_LEVEL;*/
362     /*
363      * N.B. if changes are made to the condition 
364      * for stacking, make sure that the free_sym 
365      * function remains consistent.
366      */
367     if (!isconst(e1->Type) &&
368         e1->Tab == stand_tab && e1->Sclass != c_typedef &&
369         e1->Val.sym->val.ival == -1) 
370         EiC_stackit(e1->Val.sym, level);
371 }
372
373 #if 1
374
375
376 static size_t TempSz = 0;
377
378 void EiC_clearTempories(void)
379 {
380     void EiC_updateLocals(void);
381     extern unsigned  CurTemp,EiC_ASPOT;
382     if(CurTemp) {
383         EiC_updateLocals();
384         EiC_ENV->lsp = EiC_ENV->lsp > CurTemp ?  EiC_ENV->lsp - CurTemp: 0;
385         EiC_ASPOT = EiC_ASPOT > TempSz ? EiC_ASPOT - TempSz : 0;
386         TempSz = CurTemp = 0;
387     }
388 }
389  
390 static void newSlot(token_t * E, size_t sz, val_t *v, int align)
391 {
392     extern unsigned EiC_ASPOT;
393     /* Non static locals */
394     static val_t v2;
395
396     if(IsTemp(E->Type))
397         TempSz += (sz + RoundUp(EiC_ASPOT,align) - EiC_ASPOT);
398     
399     if (EiC_ASPOT != 0)
400         EiC_ASPOT = RoundUp(EiC_ASPOT,align);
401
402     v2.ival = -1;
403
404     /* the lda instruction relies on stoptr
405      * being the next instruction, so don't change
406      * unless made compatible with 'lda' usage 
407      * in interpret.c. 
408      */
409
410     EiC_generate(&E->Code,lda,&v2,EiC_ASPOT); 
411     EiC_generate(&E->Code, stoptr, v, 1);
412     EiC_ASPOT += sz;
413     
414 }
415 #endif
416
417 static void new_var(token_t * e1)
418 {
419     int t = EiC_gettype(e1->Type);
420   
421     e1->Type = EiC_revtype(e1->Type);
422     establish_id(e1);
423     check_decl(e1);
424     if (e1->Sym) {
425         if(EiC_gettype(e1->Type) == t_enum && e1->Tab != tag_tab)
426           cast_t_enum(e1);
427
428         EiC_newsymtype(e1->Sym, e1->Type);    
429         if (!(e1->Sym->sclass == c_typedef) && !INPARMLIST)
430             if (e1->Tab == stand_tab &&
431                 ((t = EiC_gettype(e1->Type)) == t_array ||
432                  t == t_struct || t == t_union)) {
433                 val_t v;
434                 token_t *E;
435                 v.ival = EiC_get_sizeof(e1->Sym->type);
436                 /*
437                  * Here we must consider 3 types
438                  * of aggregate data: (1) local,
439                  * (2) local but static and
440                  * (3) global.
441                  * Global and local static data
442                  * get placed on the global stack.
443                  * Local data goes on the local stack.
444                  */
445                 if (EiC_INFUNC && (e1->Sym->sclass & c_static)) { 
446                     E = EiC_RETURNEXPR;
447                     EiC_add_func_static(EiC_getInf(EiC_RETURNEXPR->Type),
448                                     e1->Sym->val.ival);
449                 } else
450                     E = e1;
451         
452                 if (/*IsTemp(E->type) ||*/ (E->Sym->level > 1 && E != EiC_RETURNEXPR)) {
453
454                     newSlot(E,v.ival,&e1->Sym->val,EiC_get_align(e1->Type));
455
456                 } else {
457                     /*
458                      * Globals and static local arrays/structs
459                      * are made on the fly. However, if not
460                      * NULL, assume memory has already been allocated.
461                      */
462                     int sz;
463                     sz = v.ival > 1? v.ival:1;
464                     
465                     if(isconst(e1->Type)) {
466                         if(e1->Sym->val.ival == -1) /* not very safe ! */
467                             e1->Sym->val.p.p = (void*)
468                                 xcalloc(1,sz);
469                     } else {
470                         if(!EiC_ENV->AR[e1->Sym->val.ival].v.p.p)
471                             EiC_ENV->AR[e1->Sym->val.ival].v.p.p
472                                 = (void*)xcalloc(1,sz);
473                     }
474                 }
475             }
476     }
477 }
478
479 static void addreturn(token_t * e1, code_t * c)
480 {
481     val_t v;
482     int  i, n, lcode, rtn;
483     int err = 1; /* expect an error */
484     int EiC_analyseCode(code_t *c);
485
486     if(EiC_ParseError)
487         return;
488
489     n = nextinst(c) - 1;
490     lcode = opcode(c,n);
491     rtn = EiC_analyseCode(c);
492     
493     if(lcode == eicreturn && rtn <= n)
494         return;
495         /*printf("rtn = %d possible %s\n",rtn,e1->Sym->id);*/
496     
497     if (lcode == fmem) { /* free memory */
498         /* The last instruction is fmem. Thus, force all
499          * return calls within the function
500          * to exit via fmem
501          */
502         if(rtn <= n - 1  && opcode(c,n-1) == eicreturn)
503             err=0; /* no possible error */
504         for(i = 0; i < n; ++i)
505             if(c->inst[i].opcode == eicreturn) {
506                 c->inst[i].opcode = jmpu;
507                 c->inst[i].val.ival = n - i;
508             }
509         rtn = n;
510     }
511     if(rtn >= n) {
512         EiC_generate(c, eicreturn, &v, 0);
513         if(EiC_gettype(nextType(e1->Type))  != t_void && err)
514             EiC_warningerror("Flow reaches end "
515                          "of non-void function `%s'",
516                          e1->Sym->id);
517     }
518 }
519
520 int EiC_ext_decl(token_t * e1)
521 {
522     int h;
523     e1->Pflag = 0;
524     switch (EiC_lexan()) {
525       TYPEQUAL:
526       STORECLASS:
527       TYPESPEC:
528         h = RESET;
529         RESET = 0;
530         decl_spec(e1);
531         f_ext_decl(e1);
532     /* Hawk change */
533     if(e1->Sym && e1->Sym->type)
534         e1->Sym->type->sym = e1->Sym;
535     /* Hawk end change */
536         EiC_clearTempories();
537         RESET = h;
538         break;
539       default:
540         retractlexan();
541         return 0;
542     }
543     return 1;
544 }
545
546 static void f_ext_decl(token_t * e1)
547 {
548     switch (EiC_lexan()) {
549       DECL:
550         decl(e1, token->Tok);
551         ff_ext_decl(e1);
552         break;
553       case ';':
554         break;
555       default:
556         EiC_error("Declaration error");
557         EiC_match(';', " ; ");
558     }
559 }
560
561 token_t *EiC_genTemporay(type_expr *type, int level)
562 {
563     token_t *e1 = xcalloc(sizeof(token_t),1);
564     extern symentry_t * EiC_nxtTemp(int obj, int level);
565     symentry_t * sym;
566
567     sym = EiC_nxtTemp(ID,level);
568     EiC_inittoken(e1);
569     SetTemp(type);
570     e1->Type = EiC_copytype(type);
571     e1->Val.sym =  sym;
572     e1->Tab = sym->nspace;
573     new_var(e1);
574     e1->Val = sym->val;
575     return e1;
576
577     
578 }
579
580 static void do_Gotos(code_t *c)
581 {
582     if(c->gotos) {
583         Label_t *go, *lab;
584         go = c->gotos;
585         while(go) {
586             lab = c->labels;
587             while(lab && strcmp(lab->name,go->name) != 0)
588                 lab = lab->nxt;
589             if(lab) 
590                 ivalcode(c,go->loc) = lab->loc - go->loc;
591             else
592                 EiC_error("Missing label `%s' defined at line %d",go->name,instline(c,go->loc));
593             go = go->nxt;
594         }
595     }
596 }
597     
598 static void ff_ext_decl(token_t * e1)
599 {
600
601     extern void EiC_UpdateEntry(symentry_t * sym);
602
603     int t;
604     switch (EiC_lexan()) {
605       case '{': /* handle funtion definition */
606
607         if (EiC_S_LEVEL > 1) {
608           EiC_error("Illegal function definition in %s",EiC_RETURNEXPR->Sym->id);
609           break; 
610         }
611         new_var(e1);
612
613         if((t = EiC_gotMissingNames(EiC_getInf(e1->Type))))
614             EiC_error("Missing name for Paramater %d",t);
615         
616         if(EiC_ErrorRecover) /* force recovery */
617             EiC_ErrorRecover = 0;
618         
619         if((t = EiC_gettype(e1->Type)) == t_funcdec || t == t_func) {
620             token_t e2;
621             code_t *code;
622
623             EiC_inittoken(&e2);
624
625             if(EiC_HasHiddenParm(e1->Type)) 
626                 EiC_addoffsettolevel(stand_tab, EiC_S_LEVEL+1,2);
627             else
628                 EiC_addoffsettolevel(stand_tab, EiC_S_LEVEL+1,1);
629
630             retractlexan();
631             if (e1->Sym->ass) {
632                 EiC_warningerror("Function Re-definition of %s",e1->Sym->id);
633                 EiC_freeFuncComments(EiC_getInf(e1->Type));
634             }
635
636             /* Update declaration to definition. */
637             EiC_exchtype(t_func, e1->Type);
638             EiC_INFUNC = 1;
639             EiC_RETURNON++;
640             EiC_RETURNEXPR = e1;
641             EiC_stmt(&e2);
642
643             EiC_RETURNON--;
644             EiC_reset_env_pointers(e1, LSP);
645
646             do_Gotos(&e2.Code);
647              /* remove reducear,  if present */
648             if(e2.Code.nextinst != 0) { 
649                 if (e2.Code.inst[e2.Code.nextinst - 1].opcode ==
650                     reducear)
651                     e2.Code.nextinst--;
652                     addreturn(e1,&e2.Code);
653             } else {
654                 EiC_warningerror("Empty function definition");
655                 EiC_generate(&e2.Code, eicreturn, &e2.Val, 0);    
656             }
657             if(!EiC_ParseError) {
658                 if(e1->Sym->ass)
659                     EiC_killcode(e1->Sym);
660                 code = (code_t *) xcalloc(1, sizeof(code_t));
661                 e1->Sym->ass = 1;
662                 *code = e2.Code;
663                 EiC_ENV->AR[e1->Sym->val.ival].v.p.p = code;
664                 codeName(code) = CurrentFileName();
665             } else {
666                 void EiC_cleancode(code_t *);
667                 EiC_cleancode(&e2.Code);
668                 EiC_freecode(&e2.Code);
669             }
670                 
671             EiC_freetype(e2.Type);
672             e1->Type = NULL;    /* hide new type */
673             EiC_INFUNC = 0;
674         } else {
675             e1->Type = NULL;
676             retractlexan();
677         }
678         break;
679       default:
680         if (e1->Val.sym) {
681           
682           if(token->Tok == '@') {   /* watch for reference declaration */
683               e1->Type = EiC_revtype(e1->Type);
684               e1->Type = EiC_addtype(t_ref,e1->Type);
685               EiC_setAsBaseType(e1->Type);
686           }
687           new_var(e1);
688         }
689
690         EiC_remlevel(EiC_S_LEVEL + 1);
691         if(token->Tok == ASS) {
692             initialiser(e1);
693             EiC_lexan();
694         } else if(token->Tok == '@') {
695           handle_address_operator(e1);
696           EiC_lexan();
697         }
698         fff_ext_decl(e1);
699     }
700 }
701
702 static void fff_ext_decl(token_t * e1)
703 {
704     if (RESET) {
705         EiC_reset_env_pointers(e1, LSP);
706         RESET--;
707     }
708     setBoundaryLimits(e1);
709
710     if(EiC_gettype(e1->Type) == t_array &&
711        !EiC_get_sizeof(nextType(e1->Type)))
712         EiC_error("Ilegal size specified for %s", e1->Sym->id);
713
714
715     if (token->Tok == ',') {
716         
717         init_decl_list(e1);
718         e1->Type = NULL;        /* hide new type */
719         EiC_match(';', " ;");
720     } else {
721         retractlexan();
722         semi_colon(e1);
723     }
724
725
726
727
728 }
729
730 static void semi_colon(token_t * e1)
731 {
732     e1->Type = NULL;    /* hide new type */
733     if(!EiC_match(';', ";"))
734         retractlexan();
735 }
736
737 static void decl_spec(token_t * e1)
738 {
739     int sclass = 0;
740     void specifier(token_t *e1, int,int *sclass);
741
742     switch (token->Tok) {
743       STORECLASS:
744       TYPEQUAL:
745       TYPESPEC:
746         specifier(e1, token->Tok,&sclass);
747         if ((sclass == c_auto || sclass == c_register)
748             && !(EiC_INFUNC || EiC_S_LEVEL > 1))
749             EiC_error("Illegal storage class usage");
750         else if(INPARMLIST && sclass && sclass != c_register)
751             EiC_error("Illegal storage class for parameter %s",EiC_LEXEM);
752         else
753             e1->Sclass = sclass;
754         EiC_setAsBaseType(e1->Type);
755         /* default:
756         retractlexan();
757         */
758     }
759 }
760
761 static void specifier(token_t *e1, int t,int *sclass)
762 {
763     /* This function was modelled from lcc32's
764      * specifier function
765      */
766
767     int cls, cons, sign, size, type, vol,ty;
768     cls = ty = vol = cons = sign = size = type=0;
769
770     if(sclass == NULL)
771       cls = c_auto;
772         
773     while(1){
774       int *p, tt = t;
775       switch (t) {
776       case autosym:     tt = c_auto;     p = &cls; break;  
777       case externsym:   tt = c_extern;   p = &cls; break;  
778       case registersym: tt = c_register; p = &cls; break;  
779       case staticsym:   tt = c_static;   p = &cls; break;  
780       case typedefsym:  tt = c_typedef;  p = &cls; break;  
781       case constsym:   p = &cons;       break;
782       case volatilesym:p = &vol;        break;
783       case signedsym:
784       case unsignedsym:p = &sign;       break;
785       case longsym:
786         if(size == longsym) {
787           size = 0;
788           tt = longsym+longsym;
789         }
790
791       case shortsym:   p = &size;      break;
792       case voidsym:    ty = t_void;   p = &type;   break;
793       case charsym:    ty = t_char;   p = &type;   break;
794       case intsym:     ty = t_int;    p = &type;   break;
795       case floatsym:   ty = t_float;  p = &type;   break;
796       case doublesym:  ty = t_double; p = &type;   break;
797       case enumsym:     
798       case structsym:
799       case unionsym:   {
800         token_t e2;
801         p = &type;
802         EiC_inittoken(&e2);
803         if (t == enumsym)
804              enum_spec(&e2);
805              else
806              st_un_spec(&e2, t);
807         /*
808          *  test tag name.
809          */
810         if (e2.Val.sym) {
811           e1->Type = EiC_copytype(e2.Type);
812           e1->Tab = stand_tab;
813           if(INSTUN)
814             addst_un_tag(e2.Val.sym);
815         } else {
816           int sclass = e1->Sclass;
817           *e1 = e2;
818           e1->Sclass = sclass;
819           if(t == enumsym)
820             cast_t_enum(e1);
821         }
822       }
823       break;
824       case TYPENAME:
825         if(type == 0 && p != &sign && p != &size) {
826           e1->Type = EiC_copytype(token->Val.sym->type);
827           p = &type;
828         } else { /* allow for masking and redeclarations */
829 #if 1
830           if(checklevel(e1,token->Val.sym,EiC_S_LEVEL) || 
831                 cls == c_typedef) {
832             token->Tok = ID;
833             retractlexan();
834           } else 
835             EiC_error("Illegal use of typedef %s",token->Val.sym->id); 
836           p = NULL;
837 #else
838           token->Tok = ID;
839           retractlexan();
840           p = NULL;
841 #endif 
842         }
843         break;
844             
845       default:
846         retractlexan();
847         p = NULL;
848       }
849       if (p == NULL)
850         break;
851       if (*p)
852         EiC_error("invalid specification");
853       *p = tt;
854       t = EiC_lexan();
855     }
856     if(sclass)
857         *sclass = cls;
858     if(type == 0) {
859         type = intsym;
860         ty = t_int;
861     }
862     if ((size == shortsym && type != intsym)
863         ||  (size == longsym  && type != intsym && type != doublesym)
864         ||  (sign && type != intsym && type != charsym))
865                 EiC_error("invalid type specification");
866     if (type == charsym && sign)
867         ty = sign == unsignedsym ? t_uchar : t_char;
868     else if (size == shortsym)
869         ty = sign == unsignedsym ? t_ushort : t_short;
870     else if (size == longsym && type == doublesym)
871         ty = t_double;
872     else if (size == longsym+longsym) { 
873
874 #ifndef NO_LONG_LONG
875       ty = t_llong;
876 #else
877       ty = sign == unsignedsym ? t_ulong : t_long;
878 #endif
879
880     } else if (size == longsym)
881         ty = sign == unsignedsym ? t_ulong : t_long;
882     else if (sign == unsignedsym && type == intsym)
883         ty = t_uint;
884
885       
886     if(ty)
887         e1->Type = EiC_addtype(ty,e1->Type);
888
889     if (cons == constsym) {
890         if(INPARMLIST || EiC_INFUNC)  /* */
891             setConstp(e1->Type);
892         else        
893             setConst(e1->Type);
894         /*
895         if(EiC_INFUNC && !INPARMLIST && sclass) 
896         *sclass = c_static;
897         */
898     }
899
900         
901     /* ignore volatile for now;
902        if (vol  == VOLATILE)
903        ty = qual(VOLATILE, ty);
904        */
905 }
906
907 static void init_decl_list(token_t * e1)
908 {
909     token_t e2;
910     do {
911         EiC_inittoken(&e2);
912         
913         switch (EiC_lexan()) {
914           DECL:
915             e2.Type = EiC_copyBaseType(e1->Type);
916             e2.Sclass = e1->Sclass;
917             
918             init_decl(&e2, token->Tok);
919             if (RESET) {
920                 EiC_reset_env_pointers(&e2, LSP);
921                 RESET--;
922             }
923             EiC_concode(&e1->Code, &e2.Code);
924             EiC_remlevel(EiC_S_LEVEL+1);
925             setBoundaryLimits(&e2);
926             break;
927             
928           default:
929             EiC_error("Init decl list error");
930         }
931
932         if(EiC_gettype(e2.Type) == t_array &&
933            !EiC_get_sizeof(nextType(e2.Type)))
934             EiC_error("Ilegal size specified for %s", e2.Sym->id);
935
936     } while (EiC_lexan() == ',');
937     retractlexan();
938 }
939
940 static void init_decl(token_t * e1, int ty)
941 {
942     int t;
943     decl(e1, ty);
944 #if 1
945  
946      t = EiC_lexan();
947  
948      if(t == '@') {   /* watch for reference declaration */
949        e1->Type = EiC_addtype(t_ref,e1->Type);
950        EiC_setAsBaseType(e1->Type);
951      }
952
953 #endif
954
955     new_var(e1);
956  
957 #if 1
958
959     if(t == ASS)
960       initialiser(e1);
961     else if(t == '@') { 
962       handle_address_operator(e1);
963     } else
964        retractlexan();
965
966 #else
967
968
969    if (EiC_lexan() == ASS) {
970         initialiser(e1);
971     } else
972         retractlexan();
973
974 #endif
975 }
976
977 static void initglobal(type_expr * type, void **addr,int lev);
978 static void initstruct(type_expr * type, void **addr,int lev);
979 static void do_struct(type_expr *type, void **addr,int lev);
980 static int initarray(type_expr * type, void ** addr, int size, int lev);
981 static void assign_var(type_expr *type, void *addr,int allow);
982 static int do_array(type_expr *type, void ** addr, int size, int lev, int inc);
983
984 static void structUnionCode(token_t * e1, token_t *e2)
985 {
986     val_t v;
987     v = e1->Val;
988     e1->Val = e1->Sym->val;
989     EiC_output(e1);
990     e1->Val = v;
991     v.ival = 1;
992     EiC_generate(&e1->Code, bump, &v, 0);
993     v.ival = EiC_get_sizeof(e2->Type);
994     EiC_generate(&e2->Code,refmem,&v,0);
995 }
996
997 static token_t * E1;
998 static void initialiser(token_t * e1)
999 {
1000     int t;
1001     int peek = EiC_lexan();
1002     retractlexan();
1003     
1004     if(EiC_GI(e1) == 0) {  /* global or static local variable */
1005         E1 = e1;
1006         if ((t =EiC_gettype(e1->Type)) <= t_pointer) { /* get scalars */
1007             int v = 1;
1008             if(e1->Sclass & c_static) /* catch statics */
1009                 v = 0;
1010             if(!isconst(e1->Type))              
1011                 assign_var(e1->Type,&EiC_ENV->AR[e1->Sym->val.ival].v,v);
1012             else {
1013                 assign_var(e1->Type,&e1->Sym->val,v);
1014                 switch(EiC_gettype(e1->Type)) {
1015                 case t_char:   e1->Sym->val.ival = e1->Sym->val.cval;break;
1016                 case t_uchar:  e1->Sym->val.ival = e1->Sym->val.ucval;break;
1017                 case t_short:  e1->Sym->val.ival = e1->Sym->val.sval;break;
1018                 case t_ushort: e1->Sym->val.ival = e1->Sym->val.usval;break;
1019                 case t_float:   e1->Sym->val.dval = e1->Sym->val.fval;break;
1020                 }
1021             }
1022         } else {
1023             if(!isconst(e1->Type))
1024                 initglobal(e1->Type,&EiC_ENV->AR[e1->Sym->val.ival].v.p.p,0);
1025             else {
1026                 initglobal(e1->Type,&e1->Sym->val.p.p,0);
1027             }
1028         }
1029     } else {    
1030         if ((t =EiC_gettype(e1->Type)) <= t_pointer /* local scalar types */
1031             || ((t == t_struct || t==t_union) && peek != '{')  
1032             ) { 
1033             if(isconst(e1->Type)) 
1034                 assign_var(e1->Type,&e1->Sym->val,0);
1035             else {
1036                 token_t e2;
1037                 val_t h; 
1038                 EiC_inittoken(&e2);
1039                 EiC_assign_expr(&e2);
1040                 if (isconst(e2.Type)) {
1041                     EiC_castconst(&e2,e1,0);        
1042                     h = e1->Val;
1043                     e1->Val = e1->Sym->val;
1044                     EiC_generate(&e1->Code,pushval,&e2.Val,0);
1045                     EiC_do_stooutput(e1);
1046                     e1->Val = h;
1047                     EiC_freetoken(&e2);
1048                 } else {
1049                     EiC_output(&e2);
1050                     EiC_castvar(&e2,e1,0);
1051                     if (t == t_struct || t == t_union)
1052                         structUnionCode(e1,&e2);
1053                     EiC_concode(&e1->Code,&e2.Code);
1054                     h = e1->Val;
1055                     e1->Val = e1->Sym->val;
1056                     EiC_do_stooutput(e1);
1057                     e1->Val = h;
1058                 }
1059                 EiC_freetoken(&e2);
1060             }
1061         } else if(EiC_INFUNC) {
1062             /* code for initialising automatic aggregate types */
1063             extern unsigned EiC_ASPOT;
1064             int s2, s1 = EiC_get_sizeof(e1->Type);
1065             val_t v;
1066             E1 = e1;
1067             
1068             if(s1)
1069                 v.p.p = xcalloc(1,s1);
1070             else
1071                 v.p.p = NULL;
1072             initglobal(e1->Type,&v.p.p,0);
1073             if((s2 = EiC_get_sizeof(e1->Type)) > s1)
1074                 EiC_ASPOT += s2 - s1;
1075             EiC_add_func_initialiser(EiC_getInf(EiC_RETURNEXPR->Type),v.p.p);
1076             EiC_generate(&e1->Code,minit,&v,s2);
1077         } else  
1078             EiC_error("Initialisation not "
1079                   "supported for non scalar local types");      
1080     }
1081 }
1082
1083 static void initglobal(type_expr * type, void **addr, int lev)
1084 {
1085     switch(EiC_gettype(type)) {
1086       case t_array:
1087         initarray(type,addr,0,lev); break;
1088       case t_struct:
1089         initstruct(type,addr,lev); break;
1090       case t_union:
1091     {
1092         struct_t * S;
1093         int n;
1094         S = EiC_getInf(type);
1095         n = S->n;
1096         S->n = 1;  /* force initialisation of first member only */      
1097         initstruct(type,addr,lev+1);
1098         S->n = n;
1099     }
1100         break;
1101       default:
1102         assign_var(type, *addr,0); break;
1103     }
1104 }
1105
1106 static void initstruct(type_expr * type, void **addr, int lev)
1107
1108     if(EiC_lexan() == '{' ) {
1109         do_struct(type,addr,lev);
1110         if(lev > 1 && EiC_lexan() != ',')
1111                 retractlexan();
1112         EiC_match('}', " }");
1113     } else { 
1114         retractlexan();
1115         if(lev > 0) 
1116             do_struct(type,addr,lev);
1117         else /* else intializer must be an expression of the same type */
1118             assign_var(type,*addr,1);
1119     }
1120 }
1121
1122 static void do_struct(type_expr *type, void **addr,int lev)
1123 {
1124     struct_t *S;
1125     int i;
1126     S = EiC_getInf(type);
1127     for(i=0;i<S->n;i++) 
1128         if(EiC_lexan() != '}') {
1129             retractlexan();
1130             *addr = (char*)*addr + S->offset[i];
1131             initglobal(S->type[i],addr,lev+1);
1132             *addr = (char*)*addr - S->offset[i];
1133             if(EiC_lexan() != ',' && i != S->n-1)
1134                 retractlexan();
1135         } else {
1136             break;
1137         }
1138
1139     retractlexan();
1140
1141 }
1142
1143 static int dostrlit(void ** addr,int ln, int sln, char * str)
1144 {    /*
1145       * parse eg. char a[] = "hello world";
1146       * or  char a[5] = "hello world";
1147       */    
1148     xmark(str,eicgstring); /* mark for garbage collector */
1149     if(ln) {
1150         if(sln >= ln)
1151             EiC_warningerror("Array of chars is too long");
1152     } else {
1153         ln = sln+1; /* allow for null at end */
1154         *addr = xrealloc(*addr,ln);
1155     }
1156    if(sln < ln)
1157         memcpy(*addr,str,sln+1);
1158    else
1159        memcpy(*addr,str,ln);
1160         
1161     return ln;
1162 }
1163
1164 static int initarray(type_expr * type, void ** addr, int size, int lev)
1165 {
1166     static int INCREMENT;
1167     
1168     if(EiC_gettype(type) == t_array) {
1169         int t,tok,s;
1170         if((tok =EiC_lexan()) == '{') {
1171             t = EiC_get_sizeof(type);
1172             if(lev == 0) 
1173                 INCREMENT = t == 0 ? EiC_get_sizeof(nextType(type)): 0;
1174             s = do_array(nextType(type),addr,t,lev,INCREMENT);
1175             if(t == 0) {
1176                 int sz = EiC_get_sizeof(nextType(type));
1177                 if(sz)
1178                     t = s/sz;
1179                 else
1180                     EiC_error("Ilegal array domain in initialisation");
1181                 setNumElems(type,t);
1182             }
1183             EiC_match('}'," }");
1184         } else if(tok == STR) { /* handle string literals */
1185             if(EiC_gettype(nextType(type)) == t_char) {
1186                 size_t sln;
1187                 t = EiC_get_sizeof(type);
1188                 sln = (char*)token->Val.p.ep - (char*)token->Val.p.p - 1;
1189                 s = dostrlit(addr,t,sln,token->Val.p.p);
1190                 if(lev == 0 && t == 0)
1191                     setNumElems(type,s);
1192             }else
1193                 EiC_error("Illegal initialisation");
1194         } else{
1195             retractlexan();
1196             if(lev > 0) /* lev indicates a recusive call */
1197                 size = do_array(nextType(type),addr,size,lev,INCREMENT);
1198             else 
1199                 EiC_error("missing { in initialisation of an array");
1200         }
1201     } else
1202         initglobal(type,addr,lev+1);
1203     return size;
1204 }
1205
1206 static int do_array(type_expr *type, void ** addr, int size, int lev, int inc)
1207 {
1208
1209     int n = 0;
1210     while(EiC_lexan() != '}') {
1211         retractlexan();
1212         if(n >= size) {
1213             if(inc) {
1214                 size += inc;
1215                 *addr = xrealloc(*addr, size);
1216                 memset((char*)*addr + size - inc, 0, inc);
1217             } else {
1218                 if(size)
1219                     EiC_error("Too many initialisers");
1220                 else
1221                     EiC_error("Illegal domain for initialisation");
1222             }
1223         }
1224         *addr = (char*)*addr + n;
1225         size = initarray(type,addr, size,lev+1);
1226         *addr = (char*)*addr - n;
1227         n += EiC_get_sizeof(type);
1228         if (EiC_lexan() != ',') 
1229             break;
1230             
1231     } 
1232     retractlexan();
1233     return size;
1234 }
1235
1236 static void assign_var(type_expr *type, void *addr,int allow)
1237 {
1238     int t;
1239     token_t e1,e2;
1240     void *EiC_getaddress(token_t *);
1241     
1242
1243     EiC_inittoken(&e2);
1244     EiC_assign_expr(&e2);
1245
1246 #if 0
1247     if(IsTemp(e2.Type))
1248         EiC_clearTempories();
1249 #endif
1250     
1251     t = EiC_gettype(type);
1252
1253     if (isconst(e2.Type)) {
1254         e1.Type = type;
1255         EiC_castconst(&e2,&e1,0);
1256         switch(t) {
1257           case t_char:  
1258           case t_uchar:    *(char*)addr = e2.Val.ival; break;
1259           case t_short:
1260           case t_ushort:  *(short*)addr = e2.Val.ival; break;
1261           case t_int:
1262           case t_uint:     *(int *)addr = e2.Val.ival; break;
1263           case t_long:
1264           case t_ulong:    *(long*)addr = e2.Val.lval; break;
1265         case t_llong:      *(eic_llong*)addr = e2.Val.llval; break;
1266           case t_float:   *(float*)addr = e2.Val.dval; break;
1267           case t_double: *(double*)addr = e2.Val.dval; break;
1268           case t_pointer: 
1269             if(EiC_S_LEVEL == 1 && EiC_gettype(e2.Type) == t_pointer
1270                && EiC_gettype(nextType(e2.Type)) == t_char
1271                && !e2.Sym) 
1272                 /* got string */
1273                 if(e2.Val.p.p)
1274                     EiC_SaveGlobalString(&e2.Val.p);
1275             if(issafe(type))
1276                *(ptr_t*)addr = e2.Val.p;
1277             else
1278                *(void**)addr = e2.Val.p.p;
1279             break;
1280             
1281           default:
1282             EiC_error("Unknown initialiserXXX");
1283         }
1284     } else if(allow) {
1285         val_t h;
1286         token_t e3;
1287         EiC_inittoken(&e3);
1288         e3.Type = type;
1289         EiC_output(&e2);
1290         EiC_castvar(&e2,&e3,0); 
1291         if (t == t_struct || t == t_union) 
1292             structUnionCode(E1,&e2);
1293         h = E1->Val;
1294         E1->Val = E1->Sym->val;
1295         EiC_concode(&E1->Code,&e2.Code);
1296         EiC_do_stooutput(E1);
1297         E1->Val = h;
1298     } else {
1299         if(EiC_GI(&e2) != 0)   /* global or static addresses only are allowed */
1300             EiC_error("Illegal initialization: illegal address operation");
1301         else {
1302             /*e1.Type = type;*/
1303             /*EiC_output(&e2);*/
1304             /*EiC_castvar(&e2,&e1,1);*/
1305             if(EiC_gettype(type) == t_pointer || 
1306                        (e2.Sym && EiC_gettype(e2.Sym->type) == t_ref)) {
1307                 ptr_t p;
1308                 p.sp = p.p = EiC_getaddress(&e2);
1309                 p.ep = (char*)p.p + EiC_get_sizeof(e2.Type);
1310                 if(!EiC_sametypes(e2.Type,type))
1311                     EiC_warningerror("Suspicious pointer conversion");
1312                 if(issafe(type))
1313                     *(ptr_t*)addr = p;
1314                 else
1315                     *(void**)addr = p.p;
1316                 EiC_freecode(&e2.Code);
1317             } else
1318                 EiC_error("Expected constant expression as an"
1319                       " initialiser");
1320         }
1321     }
1322     EiC_freetoken(&e2);
1323 }
1324
1325
1326 static void decl(token_t * e1, int t)
1327 {
1328     type_expr *P = NULL;
1329     switch (t) {
1330       case '*':
1331         P = pointer();
1332         dir_decl(e1, EiC_lexan());
1333         if(P)
1334             e1->Type = EiC_catTypes(P,e1->Type);
1335         break;
1336       case ID:
1337       case '(':
1338         dir_decl(e1, t);
1339         break;
1340       default:
1341         EiC_error("Declarator error");
1342         retractlexan();
1343     }
1344
1345 }
1346
1347 static type_expr * pointer(void)
1348 {
1349     type_expr *t = NULL;
1350     do {
1351         t = EiC_addtype(t_pointer,t);
1352         if(EiC_lexan() == constsym || token->Tok == volatilesym) {
1353             if(token->Tok == constsym) {
1354                 setConstp(t);
1355             }
1356             /*ignore volatilesym for now*/
1357             EiC_lexan();
1358         }
1359         /* pointer qualifer */
1360         if(token->Tok == safesym) {
1361           unsetPtr(t);
1362
1363           setSafe(t);
1364           EiC_lexan();
1365         } else  if(token->Tok == unsafesym) {
1366           unsetPtr(t);
1367           setUnSafe(t);
1368           EiC_lexan();
1369         }
1370     } while (token->Tok == '*');
1371     retractlexan();
1372     return t;
1373 }
1374
1375 static void dir_decl(token_t * e1, int t)
1376 {
1377     switch (t) {
1378       case '(':
1379         decl(e1, EiC_lexan());
1380         EiC_match(')', " )");
1381         f_dir_decl(e1);
1382         break;
1383         
1384       case ID:
1385
1386         init_ident(e1, EiC_work_tab);
1387         f_dir_decl(e1);
1388         break;
1389         
1390       default:
1391         EiC_error("Direct declarator error");
1392         break;
1393     }
1394 }
1395
1396 static void f_dir_decl(token_t * e1)
1397 {
1398     while (1)
1399         switch (EiC_lexan()) {
1400           case '[':
1401             array_decl(e1);
1402             break;
1403           case '(':
1404             ff_dir_decl(e1);
1405             if(INPARMLIST)
1406                 EiC_remlevel(EiC_S_LEVEL+1);
1407             break;
1408           default:
1409             retractlexan();
1410             return;
1411         }
1412 }
1413
1414 static void ff_dir_decl(token_t * e1)
1415 {
1416
1417     int h;
1418     switch ((h=EiC_lexan())) {
1419       TYPEQUAL:
1420       STORECLASS:
1421       TYPESPEC:
1422         EiC_S_LEVEL++;
1423         RESET++;
1424         h = LSP;
1425         LSP = EiC_ENV->lsp;
1426         retractlexan();
1427         EiC_make_func(e1);
1428         /*
1429          * Use INPARMLIST to inform other
1430          * modules that the following declarations
1431          * are function parameters.
1432          */
1433         INPARMLIST++;
1434         PRAMHANDLE = e1->Type;
1435
1436         parm_type_list(EiC_getInf(e1->Type));
1437         /*
1438          * now pseudo reverse the parameter
1439          * order.
1440          */
1441         EiC_reset_env_pointers(e1, LSP);
1442         LSP = h;
1443         RESET--;
1444
1445         INPARMLIST--;
1446         EiC_S_LEVEL--;
1447         
1448         break;
1449       case ')':
1450         /*
1451          * This should really be made illegal, it allows
1452          * for function declarations with empty
1453          * paramater list, such as:
1454          * int f(); Therefore, force an implied t_var argument.
1455          */
1456     {
1457         type_expr * type;
1458         EiC_make_func(e1);
1459         type = EiC_addtype(t_var,NULL);
1460         EiC_add_func_parm(EiC_getInf(e1->Type), &type, NULL);
1461         EiC_freetype(type);
1462     }
1463         return;
1464       default:
1465         if(h == ID)
1466             EiC_error("Unknown type '%s': possible "
1467                   "old C type declaration", token->Val.sym->id);
1468         else
1469             EiC_error("Syntax error");
1470     }
1471     EiC_match(')', " )");
1472 }
1473
1474
1475 static void UpDateParmSym(type_expr *ty, symentry_t *sym)
1476 {
1477     if(EiC_gettype(ty) == t_pointer && EiC_gettype(nextType(ty)) ==
1478        t_funcdec)
1479         if(EiC_gettype(sym->type) != t_pointer)
1480             sym->type = EiC_addtype(t_pointer,sym->type);
1481 }
1482
1483 static void parm_type_list(func_t * f)
1484 {
1485     extern int Pclash;
1486     char * name = NULL;
1487     token_t e2;
1488     EiC_inittoken(&e2);
1489     parm_decl(&e2);
1490     /*
1491      * Must watch out for void  as a parameter.
1492      * The void paramater will have no sym entry.
1493      */
1494     if(e2.Val.sym) {
1495         new_var(&e2);
1496 #if 1
1497         {
1498             void EiC_adjustParam(type_expr **type);
1499             EiC_adjustParam(&e2.Sym->type);
1500         }
1501 #endif
1502
1503         name = e2.Sym->id;
1504     } else  /* still must reverse type if needed */
1505         e2.Type = EiC_revtype(e2.Type);
1506
1507     EiC_add_func_parm(f, &e2.Type,name);
1508     if(!e2.Val.sym)
1509         EiC_freetype(e2.Type);
1510     else
1511         UpDateParmSym(getFPty(f,getFNp(f)-1),e2.Val.sym);
1512     
1513     if(Pclash)
1514         Pclash = 0;
1515
1516     if (EiC_lexan() == ',')
1517         f_parm_type_list(f);
1518     else
1519         retractlexan();
1520 }
1521
1522 static void f_parm_type_list(func_t * f)
1523 {
1524     if (EiC_lexan() == '.') {
1525         if (EiC_lexan() == '.')
1526             if (EiC_lexan() == '.') {
1527                 type_expr *type;
1528                 type = EiC_addtype(t_var, NULL);
1529                 EiC_add_func_parm(f, &type,NULL);
1530                 EiC_freetype(type);
1531                 return;
1532             }
1533         retractlexan();
1534         EiC_error("Expected ...");
1535     } else {
1536         retractlexan();
1537         parm_type_list(f);
1538     }
1539 }
1540
1541 static void fff_parm_decl(token_t *e1);
1542 static void ff_parm_decl(token_t *e1);
1543 static void f_parm_decl(token_t * e1);
1544
1545 static void parm_decl(token_t * e1)
1546 {
1547     switch (EiC_lexan()) {
1548       TYPEQUAL:
1549       STORECLASS:
1550       TYPESPEC:
1551         decl_spec(e1);
1552         f_parm_decl(e1);
1553         break;
1554       default:
1555         if(token->Tok == ID)
1556             EiC_error("Unknown type '%s'",token->Val.sym->id);
1557         else
1558             EiC_error("Parameter declaration error");
1559     }
1560 }
1561
1562
1563 static void f_parm_decl(token_t * e1)
1564 {
1565     if(EiC_lexan() == '*') {
1566         type_expr *P = NULL;
1567         P = pointer();
1568         ff_parm_decl(e1);
1569         if(P)
1570             e1->Type = EiC_catTypes(P,e1->Type);        
1571     } else {
1572         retractlexan();
1573         ff_parm_decl(e1);
1574     }
1575 }
1576
1577
1578 static void ff_parm_decl(token_t *e1)
1579 {
1580     switch(EiC_lexan()) {
1581       case ID: init_ident(e1, EiC_work_tab);
1582         f_dir_decl(e1);
1583         break;
1584       case '(': fff_parm_decl(e1);
1585         break;
1586       case '[': retractlexan();
1587         f_dir_decl(e1);
1588         break;
1589       default: /* null */
1590         if(token->Tok  != ',' && token->Tok != ')')
1591             EiC_error("Parameter declaration error");
1592         else
1593             retractlexan();
1594         return ;        
1595     }
1596 }
1597
1598 static void fff_parm_decl(token_t *e1)
1599 {
1600     switch(EiC_lexan()) {
1601       TYPEQUAL:
1602       STORECLASS:
1603       TYPESPEC:
1604         retractlexan();
1605         ff_dir_decl(e1);
1606         EiC_remlevel(EiC_S_LEVEL+1);
1607         break;
1608       default:
1609         retractlexan();
1610         f_parm_decl(e1);
1611         EiC_match(')', " ) "); 
1612         break;
1613     }
1614     f_dir_decl(e1);
1615 }
1616
1617
1618 static void enum_spec(token_t * e1)
1619 {
1620     e1->Type = EiC_addtype(t_enum, NULL);
1621     f_enum_spec(e1);
1622 }
1623
1624 static void f_enum_spec(token_t * e1)
1625 {
1626     int h, t, nxtt;
1627     h = EiC_work_tab;
1628     EiC_work_tab = tag_tab;
1629     switch (EiC_lexan()) {
1630       case ID:                  /* enumeration tag */
1631         t = EiC_gettype(token->Val.sym->type);
1632         nxtt = EiC_lexan();
1633         retractlexan();
1634
1635         if (nxtt == '{' || t == ID) {
1636
1637             init_ident(e1, EiC_work_tab);
1638
1639
1640             new_var(e1);
1641             EiC_work_tab = h;
1642
1643             if (EiC_lexan() == '{') {
1644                 enum_list(e1);
1645                 EiC_match('}', " }");
1646                  e1->Type = e1->Val.sym->type;
1647             } else
1648                 retractlexan();
1649             break;
1650         } else if (t == t_enum) {
1651             EiC_freetype(e1->Type);
1652             e1->Type = EiC_copytype(token->Val.sym->type);
1653         } else
1654             EiC_error("Enumeration declaration error");
1655
1656         break;
1657       case '{':
1658         EiC_work_tab = h;
1659         enum_list(e1);
1660         EiC_match('}', " }");
1661         break;
1662
1663       default:
1664         EiC_error("Enumeration declaration error");
1665         retractlexan();
1666     }
1667     EiC_work_tab = h;
1668 }
1669
1670 static void enum_list(token_t * e1)
1671 {
1672     int ENUMVAL = 0;
1673     token_t e2;
1674     token_t e3;
1675     do {
1676         EiC_inittoken(&e2);
1677         /*
1678          *  now do enumerator part
1679          */
1680         if (EiC_lexan() == ID) {
1681             e2.Type = EiC_addtype(t_int, NULL);
1682             setConst(e2.Type);
1683             EiC_setAsBaseType(e2.Type);
1684             e2.Sclass = c_enum;
1685             init_ident(&e2, EiC_work_tab);
1686             new_var(&e2);
1687             if (EiC_lexan() == ASS) {
1688                 EiC_inittoken(&e3);
1689                 cond_expr(&e3);
1690                 if (isconst(e3.Type) && EiC_gettype(e3.Type) == t_int)
1691                     ENUMVAL = e3.Val.ival;
1692                 else {
1693                     EiC_freetoken(&e3);
1694                     EiC_error("Assignment must be constant");
1695                     break;
1696                 }
1697                 EiC_freetoken(&e3);
1698             } else
1699                 retractlexan();
1700             e2.Sym->val.ival = ENUMVAL++;
1701         } else {
1702             EiC_error("Expected identifier in enumeration");
1703             break;
1704         }
1705     } while (EiC_lexan() == ',');
1706     retractlexan();
1707 }
1708
1709 static void array_decl(token_t * e1)
1710 {
1711     int t;
1712     token_t e2;
1713     EiC_inittoken(&e2);
1714     EiC_assign_expr(&e2);
1715     if (isconst(e2.Type)) { 
1716         if ((t=EiC_gettype(e2.Type)) != t_int && t != t_uint) {
1717             if(sizeof(int) != sizeof(long) || t != t_ulong) {
1718                 EiC_error("Constant int expression needed");
1719                 e2.Val.ival = 0;
1720             }
1721         }
1722     } else {
1723         if(!ABSDECL && /*((t == t_void && EiC_INFUNC) || */
1724            EiC_gettype(e2.Type) != t_void )
1725             EiC_error("Constant int expression needed");
1726         e2.Val.ival = 0;
1727     }
1728     e1->Type = EiC_addtype(t_array, e1->Type);
1729     setNumElems(e1->Type,e2.Val.ival);
1730     EiC_freetoken(&e2);
1731     EiC_match(']', " ] ");
1732 }
1733
1734
1735 static void st_un_spec(token_t * e1, int t)
1736 {
1737     switch (t) {
1738       case structsym:
1739         e1->Type = EiC_addtype(t_struct, e1->Type);
1740         break;
1741       case unionsym:
1742         e1->Type = EiC_addtype(t_union, e1->Type);
1743         break;
1744     }
1745     f_st_un_spec(e1);
1746 }
1747
1748 static eicstack_t stun;
1749 static void f_st_un_spec(token_t * e1)
1750 {
1751     val_t val;
1752     int t,nxtt;
1753     symentry_t *sym;
1754     int h = EiC_work_tab;
1755     EiC_work_tab = tag_tab;
1756
1757     val.p.p = INSTUN;
1758     INSTUN = e1;
1759     EiC_eicpush(&stun,val);
1760     switch (EiC_lexan()) {
1761       case ID:                  /* struct or union tag */
1762         EiC_work_tab = h;
1763         sym = token->Val.sym;
1764         t = EiC_gettype(sym->type);
1765
1766         nxtt = EiC_lexan();
1767         retractlexan();
1768
1769         if(t==ID || (nxtt == '{' && token->Val.sym->level<EiC_S_LEVEL)) {
1770             init_ident(e1, tag_tab);
1771             new_var(e1);
1772             setInf(e1->Type,xcalloc(1, sizeof(struct_t)));
1773             if(nxtt == '{') {
1774                 
1775                 EiC_lexan();
1776                 EiC_S_LEVEL++;
1777                 s_decl_list(e1);
1778                 EiC_match('}', " }");
1779                 EiC_S_LEVEL--;
1780                 if(EiC_lexan() == ';' && EiC_S_LEVEL == 1)
1781                     e1->Type = NULL;
1782                 retractlexan();
1783                    
1784             } 
1785             
1786         } else {
1787             if (t == t_struct || t == t_union) {
1788                 EiC_freetype(e1->Type);
1789                 e1->Type = EiC_copytype(sym->type);
1790             } else {
1791                 init_ident(e1, tag_tab);
1792                 new_var(e1);
1793                 setInf(e1->Type,xcalloc(1, sizeof(struct_t)));
1794             }
1795             if(nxtt == '{') {
1796                 EiC_lexan();
1797                 EiC_S_LEVEL++;
1798                 s_decl_list(e1);
1799                 EiC_match('}', " }");
1800                 EiC_S_LEVEL--;
1801                 if(EiC_lexan() == ';' && EiC_S_LEVEL == 1) {
1802                     EiC_freetype(e1->Type);
1803                     e1->Type = NULL;
1804                 }
1805                 retractlexan();
1806             } 
1807
1808         }
1809         break;
1810       case '{':
1811         EiC_work_tab = h;
1812         EiC_S_LEVEL++;
1813         s_decl_list(e1);
1814         EiC_match('}', " }");
1815         EiC_S_LEVEL--;
1816         break;
1817     }
1818     EiC_work_tab = h;
1819     EiC_eicpop(&stun,&val);
1820     INSTUN = val.p.p;
1821
1822 }
1823
1824
1825 static void s_decl_list(token_t * e1)
1826 {
1827     int f = 0, bp = EiC_ENV->lsp;
1828     struct_t *S;
1829
1830     
1831     if(!EiC_getInf(e1->Type)) 
1832         setInf(e1->Type,xcalloc(1, sizeof(struct_t)));
1833     /*
1834     if(((struct_t*)EiC_getInf(e1->Type))->cl) {
1835         EiC_error("Illegal use of struct/union");
1836         return;
1837     }
1838     */
1839     
1840     while (1) {
1841         switch (EiC_lexan()) {
1842           TYPESPEC:
1843           TYPEQUAL:
1844                 f = 1;
1845             st_decl(e1, token->Tok);
1846             break;
1847           default:
1848             if (!f)
1849                 EiC_error("Struct/Union list declaration error");
1850             S = EiC_getInf(e1->Type);
1851             S->cl = 1;
1852             /*
1853              * determine structure alignment.
1854              */
1855
1856             S->tsize = RoundUp(S->tsize,S->align); 
1857             retractlexan();
1858             EiC_reset_env_pointers(e1, bp);
1859             return;
1860         }
1861     }
1862 }
1863
1864 static void st_decl(token_t * e1, int t)
1865 {
1866     token_t e2;
1867     EiC_inittoken(&e2);
1868     spec_qual_list(&e2, t);
1869     EiC_setAsBaseType(e2.Type);
1870     spec_declor_list(e1, &e2);
1871     EiC_freetype(e2.Type);
1872
1873     EiC_match(';', " ; ");
1874 }
1875
1876 static void spec_qual_list(token_t * e1, int t)
1877 {
1878     /*type_spec(e1, t);*/
1879     specifier(e1,t,NULL);
1880     r_spec_qual_list(e1);
1881 }
1882
1883 static void r_spec_qual_list(token_t * e1)
1884 {
1885     switch (EiC_lexan()) {
1886       TYPESPEC:
1887             spec_qual_list(e1, token->Tok);
1888         break;
1889       default:
1890         retractlexan();
1891     }
1892 }
1893
1894 void EiC_free_un_mem(type_expr * e)
1895 {
1896     struct_t *S = EiC_getInf(e);
1897     if (S) {
1898         int i;
1899         if(S->n) {
1900             for (i = 0; i < S->n; i++) {
1901                 xfree(S->id[i]);
1902                 EiC_freetype(S->type[i]);
1903             }
1904             xfree(S->offset);
1905             xfree(S->id);
1906             xfree(S->type);
1907         }
1908         if(S->ntags) {
1909             for(i=0;i<S->ntags;++i)
1910                 EiC_freetype(S->tag[i]);
1911             xfree(S->tag);
1912         }
1913         xfree(S);
1914     }
1915 }
1916
1917 static void addst_un_tag(symentry_t *sym)
1918 {
1919     struct_t *S;
1920     S = EiC_getInf(INSTUN->Val.sym->type);
1921     S->ntags++;
1922     if(S->ntags == 1)
1923         S->tag = (type_expr**)xmalloc(sizeof(type_expr*));
1924     else
1925         S->tag = (type_expr**)xrealloc(S->tag,
1926                                       sizeof(type_expr*)*S->ntags);
1927     S->tag[S->ntags - 1] = EiC_transtype(sym->type);
1928     EiC_setaliases(sym->type,1);
1929 }
1930         
1931 static void addst_un_mem(token_t * e1, token_t * e2)
1932 {
1933     struct_t *S;
1934     int off, s;
1935
1936     S = EiC_getInf(e1->Type);
1937     if (S->n == 0) {
1938         S->id = (char **) xcalloc(1, sizeof(char *));
1939         S->offset = (int *) xcalloc(1, sizeof(int));
1940         S->type = (type_expr **) xcalloc(1, sizeof(type_expr *));
1941     } else {
1942         /*
1943          * first check for duplication of names
1944          */
1945         int i;
1946         for(i=0;i<S->n;++i) 
1947             if(strcmp(S->id[i], e2->Val.sym->id) == 0)
1948                 EiC_error("Duplication of identifier in struct/union");
1949
1950         S->id = (char **) xrealloc(S->id,
1951                                    (S->n + 1) * sizeof(char *));
1952         S->offset = (int *) xrealloc(S->offset,
1953                                      (S->n + 1) * sizeof(int));
1954         S->type = (type_expr **) xrealloc(S->type,
1955                                           (S->n + 1) * sizeof(type_expr *));
1956     }
1957
1958     if(isconst(e2->Type)) {
1959         unsetConst(e2->Type);
1960         setConstp(e2->Type);
1961     }
1962
1963     if(EiC_gettype(e2->Type) == t_enum)
1964       cast_t_enum(e2);
1965
1966     S->id[S->n] = (char *) EiC_strsave(e2->Val.sym->id);
1967     S->type[S->n] = EiC_transtype(e2->Type);
1968     
1969     
1970     if(!(s = EiC_get_sizeof(S->type[S->n]))) {
1971      EiC_error("Incomplete data type for struct/union member %s",S->id[S->n]);
1972     }
1973     off = EiC_get_align(e2->Type);
1974         
1975     if (EiC_gettype(e1->Type) == t_struct) {
1976         
1977         S->offset[S->n] = RoundUp(S->tsize,off);
1978         S->tsize += s + S->offset[S->n] - S->tsize;
1979     } else { /* handle union */ 
1980         S->offset[S->n] = 0;
1981         S->tsize = S->tsize > s ? S->tsize : s;
1982     }
1983     /*
1984      * structure alignment is equal to the
1985      * maximum alignment of its members.
1986      */
1987     if(S->align < off)
1988         S->align = off;
1989     S->n++;
1990 }
1991
1992 static void spec_declor_list(token_t * e1, token_t * e2)
1993 {
1994     int ftime = 1, cl;
1995     token_t e3;
1996     cl = ((struct_t*)EiC_getInf(e1->Type))->cl;
1997     do {
1998         switch (EiC_lexan()) {
1999           case '*':
2000           case ID:
2001           case '(':
2002           case ':':
2003             EiC_inittoken(&e3);
2004             e3.Type = EiC_transtype(e2->Type);
2005             st_declor(&e3, token->Tok);
2006             if (EiC_gettype(e3.Type) == t_struct ||
2007                 EiC_gettype(e3.Type) == t_union) {
2008                 struct_t *S;
2009                 S = EiC_getInf(e3.Type);
2010                 if (!S->cl)     /* check for closure */
2011                     EiC_error("Illegal Struct/Union member");
2012             }
2013             /* if structure/union is already closed,
2014              * then assume structure is being re-entered.
2015              */
2016             if (e3.Val.sym && !cl) {
2017                 e3.Type = EiC_revtype(e3.Type);
2018                 if (ftime)
2019                     EiC_setaliases(e2->Type, 1);
2020                 addst_un_mem(e1, &e3);
2021                 if (ftime) {
2022                     EiC_setaliases(e3.Type, 1);
2023                     ftime = 0;
2024                 }
2025             }
2026             EiC_freetype(e3.Type);
2027             EiC_remsym(e3.Val.sym);
2028             break;
2029           default:
2030             retractlexan();
2031             EiC_error("Struct/Union member declaration error");
2032         }
2033     } while (EiC_lexan() == ',');
2034     retractlexan();
2035 }
2036
2037 static void st_declor(token_t * e1, int t)
2038 {
2039     switch (t) {
2040       case '*':
2041       case ID:
2042       case '(':
2043           decl(e1, t);
2044           /*setBoundaryLimits(e1);*/
2045           f_st_declor();
2046           establish_id(e1);
2047           break;
2048       case ':':
2049           EiC_error("Bit fields not supported");
2050           break;
2051     }
2052 }
2053
2054 static void f_st_declor()
2055 {
2056     if (EiC_lexan() == ':')
2057         EiC_error("Bit fields not supported");
2058     else
2059         retractlexan();
2060 }
2061
2062 int EiC_type_name(token_t * e1)
2063 {
2064     switch (EiC_lexan()) {
2065       TYPEQUAL:
2066       TYPESPEC:
2067         spec_qual_list(e1, token->Tok);
2068         EiC_setAsBaseType(e1->Type);
2069         switch (EiC_lexan()) {
2070           case '*':
2071           case '(':
2072           case '[':
2073             abs_decl(e1, token->Tok);
2074             e1->Type = EiC_revtype(e1->Type);
2075             break;
2076           default:
2077             retractlexan();
2078         }
2079         break;
2080       default:
2081         retractlexan();
2082         return 0;
2083     }
2084     return 1;
2085 }
2086
2087 static void abs_decl(token_t * e1, int t)
2088 {
2089     type_expr *P = NULL;
2090     ABSDECL++;
2091     switch (t) {
2092       case '*':
2093         P = pointer();
2094         f_abs_decl(e1);
2095         if(P)
2096             e1->Type = EiC_catTypes(P,e1->Type);
2097         break;
2098       case '(':
2099       case '[':
2100         dir_abs_decl(e1, t);
2101         break;
2102       case ID:
2103         EiC_error("extraneous identifier `%s'",token->Val.sym->id);
2104         break;
2105     }
2106     ABSDECL--;
2107 }
2108
2109 static void f_abs_decl(token_t * e1)
2110 {
2111     switch (EiC_lexan()) {
2112       case '(':
2113       case '[':
2114         dir_abs_decl(e1, token->Tok);
2115         break;
2116       case ID:
2117         EiC_error("extraneous identifier `%s'",token->Val.sym->id);
2118         break;
2119       default:
2120         retractlexan();
2121     }
2122 }
2123
2124 static void dir_abs_decl(token_t * e1, int t)
2125 {
2126     switch (t) {
2127       case '(':
2128         f1_dir_abs(e1);
2129         EiC_f2_dir_abs(e1);
2130         break;
2131       case '[':
2132         array_decl(e1);
2133         EiC_f2_dir_abs(e1);
2134         break;
2135
2136     }
2137 }
2138
2139 static void f1_dir_abs(token_t * e1)
2140 {
2141     switch (EiC_lexan()) {
2142       case ')':
2143       TYPEQUAL:
2144       STORECLASS:
2145       TYPESPEC:
2146         retractlexan();
2147         ff_dir_decl(e1);
2148         EiC_remlevel(EiC_S_LEVEL+1);
2149         break;
2150       case '*':
2151       case '(':
2152       case '[':
2153         abs_decl(e1, token->Tok);
2154         EiC_match(')', " )");
2155         break;
2156
2157       default:
2158         EiC_error("Abstract declaration error");
2159     }
2160 }
2161
2162 static void EiC_f2_dir_abs(token_t * e1)
2163 {
2164     switch (EiC_lexan()) {
2165       case '[':
2166         array_decl(e1);
2167         EiC_f2_dir_abs(e1);
2168         break;
2169       case '(':
2170         ff_dir_decl(e1);
2171         EiC_remlevel(EiC_S_LEVEL+1);
2172         EiC_f2_dir_abs(e1);
2173         break;
2174       default:
2175         retractlexan();
2176     }
2177 }