blob: 942bed7936f496e8e998ac9ce59986ac2ac45cf2 [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* $VER: vbcc (declaration.c) $Revision: 1.90 $ */
2
3#include <string.h>
4#include <stdio.h>
5
6#include "vbcc_cpp.h"
7#include "vbc.h"
8
9static char FILE_[]=__FILE__;
10
11#define PLAIN_STORAGE_CLASS 7
12#define PARAMETER 8
13#define OLDSTYLE 16
14
15void dynamic_init(Var *v,type *t,const_list *cl,zmax of,int noconst);
16int test_assignment(type *,np);
17int return_sc,return_reg,has_return,return_inline;
18char *return_vattr;
19static int did_return_label;
20#ifdef HAVE_TARGET_ATTRIBUTES
21unsigned long return_tattr;
22#endif
23zumax return_mask;
24zmax init_dyn_sz,init_const_sz;
25int init_dyn_cnt,init_const_cnt;
26
27void init_sl(struct_list *sl);
28
29#ifdef HAVE_ECPP
30/* removed */
31/* removed */
32/* removed */
33/* removed */
34/* removed */
35/* removed */
36/* removed */
37/* removed */
38/* removed */
39/* removed */
40/* removed */
41/* removed */
42/* removed */
43/* removed */
44/* removed */
45/* removed */
46/* removed */
47/* removed */
48/* removed */
49/* removed */
50/* removed */
51/* removed */
52/* removed */
53/* removed */
54/* removed */
55/* removed */
56/* removed */
57/* removed */
58/* removed */
59/* removed */
60/* removed */
61#endif
62
63extern np gen_libcall(char *,np,type *,np,type *);
64extern int float_used;
65extern void optimize(long,Var *);
66
67extern type uct;
68
69void needs(char *s)
70{
71 Var *v;
72 if(!(v=find_ext_var(s))||!strcmp(v->identifier,s)){
73 Var *needs=add_var(s,clone_typ(&uct),EXTERN,0);
74 needs->flags|=(USEDASSOURCE|REFERENCED|NEEDS);
75 }
76}
77
78static void clear_main_ret(void)
79{
80 if(c99&&!strcmp(cur_func,"main")&&return_typ&&ISSCALAR(return_typ->flags)){
81 /* in c99, main returns 0 if it falls from back */
82 IC *new=new_IC();
83 new->code=SETRETURN;
84 new->q1.val.vmax=l2zm(0L);
85 eval_const(&new->q1.val,MAXINT);
86 insert_const(&new->q1.val,return_typ->flags&NU);
87 new->q1.flags=KONST;
88 new->typf=return_typ->flags;
89 new->q2.val.vmax=szof(return_typ);
90 new->q2.flags=new->z.flags=0;
91 new->z.reg=freturn(return_typ);
92 add_IC(new);
93 }
94}
95
96static char *get_string(void)
97/* Liest Stringkonstante und liefert Wert als String (malloced) */
98{
99 np tree;int l;char *p;
100 const_list *cl;
101 killsp();
102 if(ctok->type!=T_STRING) {error(74);return 0;}
103 tree=string_expression();
104 if(!tree||tree->flags!=STRING){
105 error(229);
106 return 0;
107 }
108 cl=tree->cl;l=0;
109 while(cl){
110 l++;
111 cl=cl->next;
112 }
113 p=mymalloc(l);
114 cl=tree->cl;l=0;
115 while(cl){
116 p[l]=CHARBACK(zm2l(zc2zm(cl->other->val.vchar)));
117 l++;
118 cl=cl->next;
119 }
120 if(tree) free_expression(tree);
121 killsp();
122 return p;
123}
124
125/* checks whether string is a valid vector type */
126/* returns the dimension */
127static int check_vect(char *s,char *base)
128{
129 int i=strlen(base),dim;
130 if(strncmp(s,base,i)) return 0;
131 dim=s[i];
132 if(dim=='2'||dim=='3'||dim=='4'||dim=='8'){
133 if(s[i+1]==0)
134 return dim-'0';
135 else
136 return 0;
137 }
138 if(s[i]=='1'&&s[i+1]=='6'&&s[i+2]==0)
139 return 16;
140 return 0;
141}
142
143int settyp(int typnew, int typold)
144/* Unterroutine fuer declaration_specifiers(). */
145{
146 if(DEBUG&2) printf("settyp: new=%d old=%d\n",typnew,typold);
147 if(typold==LONG&&typnew==FLOAT){ error(203); return DOUBLE;}
148 if(typold==LONG&&typnew==DOUBLE) return LDOUBLE;
149 if(c99&&typold==LONG&&typnew==LONG) return LLONG;
150 if(typold==INT&&(typnew==SHORT||typnew==LONG)) return typnew;
151 if(typold!=0&&typnew!=INT){error(47);return(typnew);}
152 if(typold==0&&typnew==INT) return(INT);
153 if(typold==0) return(typnew);
154 if(typold==SHORT||typold==LONG||typold==LLONG) return(typold);
155 error(48);
156 return(typnew);
157}
158
159#define dsc if(storage_class) error(49); if(typ||type_qualifiers) error(50)
160#define XSIGNED 16384
161
162#ifdef HAVE_MISRA
163/* removed */
164#endif
165
166type *declaration_specifiers(void)
167/* Erzeugt neuen Typ und gibt Zeiger darauf zurueck, */
168/* parst z.B. unsigned int, bla etc. */
169{
170 int typ=0,type_qualifiers=0,notdone,storage_class,hard_reg,have_inline;
171#ifdef HAVE_ECPP
172/* removed */
173/* removed */
174/* removed */
175#endif
176 char *imerk,sident[MAXI],sbuff[MAXI],*attr=0,*vattr=0;
177 zumax mask=ul2zum(0UL);
178 type *new=new_typ(),*t,*ts;
179 struct_declaration *ssd;
180 struct_list (*sl)[];
181 size_t slsz;
182 Var *v;
183 int dim;
184#ifdef HAVE_TARGET_ATTRIBUTES
185 unsigned long tattr=0;
186#endif
187 storage_class=hard_reg=have_inline=0;
188 do{
189 killsp();notdone=0;
190 if(ctok->type==NAME){
191 if(!strcmp("struct",ctok->name)||!strcmp("union",ctok->name)||(ecpp&&!strcmp("class",ctok->name))){
192 if(!strcmp("struct",ctok->name)) notdone=STRUCT;
193 if(!strcmp("union",ctok->name)) {
194 notdone=UNION;
195#ifdef HAVE_MISRA
196/* removed */
197#endif
198 }
199#ifdef HAVE_ECPP
200/* removed */
201/* removed */
202/* removed */
203/* removed */
204/* removed */
205#endif
206 next_token();
207 killsp();
208 if(ctok->type!=LBRA){
209 cpbez(sident,1);
210 next_token();
211 killsp();
212 ssd=find_struct(sident,0);
213#ifdef HAVE_MISRA
214/* removed */
215#endif
216 if(ssd&&ctok->type==LBRA&&find_struct(sident,nesting)&&ssd->count>0) error(13,sident);
217 if(!ssd||((ctok->type==LBRA||ctok->type==SEMIC)&&!find_struct(sident,nesting))){
218 typ=settyp(notdone,typ);
219 ssd=mymalloc(sizeof(*ssd));
220 ssd->count=0;
221 new->exact=ssd=add_sd(ssd,notdone);
222 if(!ecpp)add_struct_identifier(sident,ssd);
223#ifdef HAVE_ECPP
224/* removed */
225/* removed */
226/* removed */
227/* removed */
228#endif
229 }else{
230 new->exact=ssd;
231 typ=settyp(new->flags=notdone,typ);
232 }
233 }else{
234 *sident=0;
235 typ=settyp(notdone,typ);
236 ssd=mymalloc(sizeof(*ssd));
237 ssd->count=0;
238 new->exact=ssd=add_sd(ssd,notdone);
239 }
240 if(ssd->typ!=notdone) error(230,sident);
241#ifdef HAVE_ECPP
242/* removed */
243/* removed */
244/* removed */
245/* removed */
246/* removed */
247/* removed */
248/* removed */
249/* removed */
250/* removed */
251/* removed */
252/* removed */
253/* removed */
254/* removed */
255/* removed */
256/* removed */
257/* removed */
258/* removed */
259/* removed */
260/* removed */
261/* removed */
262/* removed */
263/* removed */
264/* removed */
265/* removed */
266#endif
267 if(ctok->type==LBRA){
268 int bfoffset,bfsize,flex_array=0,cbfo=0;
269 int scount;
270 zmax off=l2zm(0L);
271 next_token();
272 killsp();
273 slsz=SLSIZE;
274 imerk=ident;
275 sl=mymalloc(slsz*sizeof(struct_list));
276 ssd->count=0;
277#ifdef HAVE_ECPP
278/* removed */
279/* removed */
280/* removed */
281/* removed */
282/* removed */
283/* removed */
284/* removed */
285/* removed */
286/* removed */
287/* removed */
288/* removed */
289#endif
290 scount=ssd->count;
291 ts=declaration_specifiers();
292 while(ctok->type!=RBRA&&ts){
293 if(flex_array) error(231);
294 ident=sbuff;
295 t=declarator(clone_typ(ts));
296 killsp();
297 bfsize=bfoffset=-1;
298 if(ctok->type==T_COLON){
299 np tree;
300 if((ts->flags&NQ)!=INT) {
301 error(51);
302#ifdef HAVE_MISRA
303/* removed */
304#endif
305 }
306 next_token();killsp();tree=assignment_expression();
307
308 if(type_expression(tree,0)){
309 int tsize;
310 if(tree->flags!=CEXPR) error(52);
311 if(!ISINT(tree->ntyp->flags)) error(52);
312 eval_const(&tree->val,tree->ntyp->flags);
313 bfsize=(int)zm2l(vmax);
314 tsize=(int)zm2l(zmmult(sizetab[t->flags&NQ],char_bit));
315 if(bfsize<0||bfsize>tsize||(bfsize==0&&*ident)){
316 error(332);bfsize=1;
317 }
318 if(bfsize+cbfo>tsize){
319 bfoffset=cbfo=0;
320 }else{
321 bfoffset=cbfo;
322 }
323 if(bfsize!=0)
324 cbfo+=bfsize;
325 else
326 cbfo=0;
327 }
328#ifdef HAVE_MISRA
329/* removed */
330/* removed */
331/* removed */
332#endif
333 if(tree) free_expression(tree);
334 }else{
335 if(!ecpp&&*ident==0) error(53);
336 cbfo=0;
337 }
338#ifdef HAVE_ECPP
339/* removed */
340/* removed */
341/* removed */
342/* removed */
343/* removed */
344/* removed */
345/* removed */
346/* removed */
347/* removed */
348/* removed */
349/* removed */
350/* removed */
351/* removed */
352/* removed */
353/* removed */
354/* removed */
355#endif
356 if(type_uncomplete(t)){
357 if(!c99||notdone!=STRUCT||flex_array||(t->flags&NQ)!=ARRAY||type_uncomplete(t->next)){
358 error(14,sbuff);
359 freetyp(t);
360 break;
361 }else{
362 flex_array=1;
363 }
364 }
365 if(ISARRAY(t->flags)&&t->dsize){
366 error(352,sbuff);
367 }
368 if(ISFUNC(t->flags)){
369 if(!ecpp){
370 error(15,sbuff);
371 }
372 }
373 if(*ident!=0){
374 int i=scount;
375 while(--i>=0)
376 if(!strcmp((*sl)[i].identifier,ident))
377 error(16,ident);
378 }
379#ifdef HAVE_MISRA
380/* removed */
381#endif
382#ifdef HAVE_ECPP
383/* removed */
384/* removed */
385/* removed */
386/* removed */
387/* removed */
388/* removed */
389/* removed */
390/* removed */
391/* removed */
392/* removed */
393/* removed */
394/* removed */
395/* removed */
396/* removed */
397/* removed */
398/* removed */
399/* removed */
400/* removed */
401/* removed */
402/* removed */
403/* removed */
404/* removed */
405/* removed */
406/* removed */
407/* removed */
408/* removed */
409/* removed */
410/* removed */
411/* removed */
412/* removed */
413/* removed */
414/* removed */
415/* removed */
416/* removed */
417/* removed */
418/* removed */
419/* removed */
420/* removed */
421/* removed */
422/* removed */
423/* removed */
424/* removed */
425#endif
426 (*sl)[scount].bfoffset=bfoffset;
427 (*sl)[scount].bfsize=bfsize;
428 (*sl)[scount].styp=t;
429 if(!ecpp) (*sl)[scount].identifier=add_identifier(ident,strlen(ident));
430#ifdef HAVE_ECPP
431/* removed */
432/* removed */
433/* removed */
434#endif
435 if(pack_align>0&&pack_align<falign(t))
436 (*sl)[scount].align=pack_align;
437 else
438 (*sl)[scount].align=falign(t);
439 {
440 zmax m,al=(*sl)[scount].align;
441 zmax sz=szof(t);
442 m=off;
443 if((zmeqto(al,l2zm(0L))||zmeqto(sz,l2zm(0L)))&&!flex_array){
444 if (!ecpp){
445 error(316,ident);
446 }
447 }else{
448 off=zmmult(zmdiv(zmadd(off,zmsub(al,l2zm(1L))),al),al);
449 if(!zmeqto(m,off)) error(306,ident);
450 if(!flex_array){
451 m=zmmult(zmdiv(zmadd(off,zmsub(sz,l2zm(1L))),sz),sz);
452 if(!zmeqto(m,off)) error(307,ident);
453 off=zmadd(off,sz);
454 }
455 }
456 }
457 scount++;
458 if(scount>=slsz-1){
459 slsz+=SLSIZE;
460 sl=myrealloc(sl,slsz*sizeof(struct_list));
461 }
462 killsp();
463 if(ctok->type==COMMA) {next_token();killsp();continue;}
464 if(ctok->type!=SEMIC) error(54); else next_token();
465 killsp();
466#ifdef HAVE_ECPP
467/* removed */
468#endif
469 if(ctok->type!=RBRA){
470 if(ts) freetyp(ts);
471 ts=declaration_specifiers();killsp();
472 }
473 }
474 if(ts) freetyp(ts);
475 ssd->count=scount;
476 if(ssd->count==0) error(55);
477#ifdef HAVE_ECPP
478/* removed */
479/* removed */
480/* removed */
481/* removed */
482/* removed */
483/* removed */
484/* removed */
485/* removed */
486/* removed */
487/* removed */
488/* removed */
489/* removed */
490/* removed */
491/* removed */
492/* removed */
493/* removed */
494/* removed */
495/* removed */
496/* removed */
497/* removed */
498/* removed */
499/* removed */
500/* removed */
501/* removed */
502/* removed */
503/* removed */
504/* removed */
505/* removed */
506/* removed */
507/* removed */
508/* removed */
509/* removed */
510/* removed */
511/* removed */
512/* removed */
513/* removed */
514/* removed */
515/* removed */
516/* removed */
517/* removed */
518/* removed */
519/* removed */
520/* removed */
521/* removed */
522/* removed */
523/* removed */
524/* removed */
525/* removed */
526/* removed */
527/* removed */
528/* removed */
529/* removed */
530/* removed */
531/* removed */
532/* removed */
533/* removed */
534/* removed */
535/* removed */
536/* removed */
537/* removed */
538/* removed */
539/* removed */
540/* removed */
541/* removed */
542/* removed */
543/* removed */
544/* removed */
545/* removed */
546/* removed */
547/* removed */
548/* removed */
549/* removed */
550/* removed */
551/* removed */
552/* removed */
553/* removed */
554/* removed */
555/* removed */
556/* removed */
557/* removed */
558/* removed */
559/* removed */
560/* removed */
561/* removed */
562/* removed */
563/* removed */
564/* removed */
565/* removed */
566/* removed */
567/* removed */
568/* removed */
569/* removed */
570/* removed */
571/* removed */
572/* removed */
573/* removed */
574/* removed */
575/* removed */
576/* removed */
577/* removed */
578/* removed */
579/* removed */
580/* removed */
581/* removed */
582/* removed */
583/* removed */
584/* removed */
585/* removed */
586/* removed */
587/* removed */
588/* removed */
589/* removed */
590/* removed */
591/* removed */
592/* removed */
593/* removed */
594/* removed */
595/* removed */
596/* removed */
597/* removed */
598/* removed */
599/* removed */
600/* removed */
601/* removed */
602/* removed */
603/* removed */
604/* removed */
605/* removed */
606/* removed */
607/* removed */
608/* removed */
609/* removed */
610/* removed */
611/* removed */
612/* removed */
613/* removed */
614/* removed */
615/* removed */
616/* removed */
617/* removed */
618/* removed */
619/* removed */
620/* removed */
621/* removed */
622/* removed */
623/* removed */
624/* removed */
625/* removed */
626#endif
627 ident=imerk;
628 add_sl(ssd,sl);
629 free(sl);
630 if(ctok->type!=RBRA) error(56); else next_token();
631 new->flags=notdone|type_qualifiers;
632 }
633#ifdef HAVE_ECPP
634/* removed */
635#endif
636 notdone=1;
637 }else if(!strcmp("enum",ctok->name)){
638 /* enumerations; die Namen werden leider noch ignoriert */
639 next_token();killsp();notdone=1;
640 if(ctok->type!=LBRA){cpbez(buff,1);next_token();killsp();}
641 if(ctok->type==LBRA){
642 /* mode: 0=start 1=first was not init 2=first was init 3=more init */
643 zmax val; Var *v; type *t;int mode=0;
644 val=l2zm(0L);
645 next_token();killsp();
646 while(ctok->type!=RBRA){
647 cpbez(sident,1);next_token();killsp();
648 if(*sident==0) {error(56);break;}
649 t=new_typ();
650 t->flags=CONST|INT;
651 if(find_var(sident,nesting)) error(17,sident);
652 v=add_var(sident,t,AUTO,0); /* AUTO hier klug? */
653 if(ctok->type==ASGN){
654 if(mode==2) mode=3;
655 if(mode==0) mode=2;
656#ifdef HAVE_MISRA /* MISRA Rule 9.3 checking */
657/* removed */
658#endif
659 next_token();killsp();
660 v->clist=initialization(v->vtyp,0,0,0,0,0);
661 val=zi2zm(v->clist->val.vint);killsp();
662 }else{
663 if(mode==0) mode=1;
664#ifdef HAVE_MISRA /* MISRA Rule 9.3 checking */
665/* removed */
666#endif
667 v->clist=mymalloc(CLS);
668 v->clist->val.vint=zm2zi(val);
669 v->clist->next=v->clist->other=0;
670 v->clist->tree=0;
671 v->clist->idx=l2zm(0L);
672 }
673 vmax=l2zm(1L);val=zmadd(val,vmax);
674 v->vtyp->flags=CONST|ENUM;
675 if(ctok->type!=RBRA&&ctok->type!=COMMA) {error(56);break;}
676 if(ctok->type==COMMA) next_token();
677 killsp();
678 if(ctok->type==RBRA) {next_token(); break;}
679 }
680 }
681 killsp();
682 typ=settyp(INT,typ);
683 }else if(!strcmp("__readsmem",ctok->name)||!strcmp("__writesmem",ctok->name)){
684 enum {READS,WRITES} op;
685 char *imerk,tbuf[MAXI];
686 type *tmp;
687 if(!strcmp("__readsmem",ctok->name))
688 op=READS;
689 else
690 op=WRITES;
691 next_token();killsp();
692 if(ctok->type==LPAR) next_token(); else error(151);
693 imerk=ident;ident=tbuf;
694 tmp=declarator(declaration_specifiers());
695 ident=imerk;
696 if(tmp){
697 if(vattr)
698 vattr=myrealloc(vattr,strlen(vattr)+25);
699 else{
700 vattr=mymalloc(25);
701 vattr[0]=0;
702 }
703 sprintf(vattr+strlen(vattr),";%s(%d)",op==READS?"readmem":"writemem",tmp->flags);
704 }
705 killsp();
706 if(ctok->type==RPAR) next_token(); else error(59);
707 killsp();
708 notdone=1;
709 }else if(!strcmp("void",ctok->name)){
710 next_token();
711 typ=settyp(VOID,typ);notdone=1;
712 }else if(!strcmp("char",ctok->name)){
713#ifdef HAVE_MISRA
714/* removed */
715/* removed */
716#endif
717 next_token();
718 typ=settyp(CHAR,typ);
719 notdone=1;
720 if(default_unsigned&&!(type_qualifiers&XSIGNED))
721 type_qualifiers|=UNSIGNED;
722 }else if(!strcmp("short",ctok->name)){
723#ifdef HAVE_MISRA
724/* removed */
725#endif
726 next_token();
727 typ=settyp(SHORT,typ);notdone=1;
728 }else if(!strcmp("int",ctok->name)){
729#ifdef HAVE_MISRA
730/* removed */
731#endif
732 next_token();
733 typ=settyp(INT,typ);notdone=1;
734 }else if(!strcmp("long",ctok->name)){
735#ifdef HAVE_MISRA
736/* removed */
737#endif
738 next_token();
739 typ=settyp(LONG,typ);notdone=1;
740 }else if(!strcmp("float",ctok->name)){
741#ifdef HAVE_MISRA
742/* removed */
743#endif
744 next_token();
745 typ=settyp(FLOAT,typ);notdone=1;
746 }else if(!strcmp("double",ctok->name)){
747#ifdef HAVE_MISRA
748/* removed */
749#endif
750 next_token();
751 typ=settyp(DOUBLE,typ);notdone=1;
752 }else if(!strcmp("const",ctok->name)){
753 next_token();
754 if(type_qualifiers&CONST) error(58);
755 type_qualifiers|=CONST;notdone=1;
756 }else if(!strcmp("volatile",ctok->name)){
757 next_token();
758 if(type_qualifiers&VOLATILE) error(58);
759 type_qualifiers|=VOLATILE;notdone=1;
760 }else if(opencl&&(dim=check_vect(ctok->name,"bool"))){
761 next_token();
762 typ=settyp(VECBOOL+dim-1,typ);
763 notdone=1;
764 }else if(opencl&&(dim=check_vect(ctok->name,"char"))){
765 next_token();
766 typ=settyp(VECCHAR+dim-1,typ);
767 notdone=1;
768 }else if(opencl&&(dim=check_vect(ctok->name,"uchar"))){
769 next_token();
770 typ=settyp((VECCHAR+dim-1)|UNSIGNED,typ);
771 notdone=1;
772 }else if(opencl&&(dim=check_vect(ctok->name,"short"))){
773 next_token();
774 typ=settyp(VECSHORT+dim-1,typ);
775 notdone=1;
776 }else if(opencl&&(dim=check_vect(ctok->name,"ushort"))){
777 next_token();
778 typ=settyp((VECSHORT+dim-1)|UNSIGNED,typ);
779 notdone=1;
780 }else if(opencl&&(dim=check_vect(ctok->name,"int"))){
781 next_token();
782 typ=settyp(VECINT+dim-1,typ);
783 notdone=1;
784 }else if(opencl&&(dim=check_vect(ctok->name,"uint"))){
785 next_token();
786 typ=settyp((VECINT+dim-1)|UNSIGNED,typ);
787 notdone=1;
788 }else if(opencl&&(dim=check_vect(ctok->name,"long"))){
789 next_token();
790 typ=settyp(VECLONG+dim-1,typ);
791 notdone=1;
792 }else if(opencl&&(dim=check_vect(ctok->name,"ulong"))){
793 next_token();
794 typ=settyp((VECLONG+dim-1)|UNSIGNED,typ);
795 notdone=1;
796 }else if(opencl&&(dim=check_vect(ctok->name,"float"))){
797 next_token();
798 typ=settyp(VECFLOAT+dim-1,typ);
799 notdone=1;
800#if 0
801 }else if(c99&&!strcmp("restrict",ctok->name)){
802 next_token();
803 if(type_qualifiers&RESTRICT) error(58);
804 type_qualifiers|=RESTRICT;notdone=1;
805#endif
806 }else if(!strcmp("unsigned",ctok->name)){
807 next_token();
808 if(type_qualifiers&(XSIGNED|UNSIGNED)) error(58);
809 notdone=1;type_qualifiers|=UNSIGNED;
810 }else if(!strcmp("signed",ctok->name)){
811 next_token();
812 if(type_qualifiers&(XSIGNED|UNSIGNED)) error(58);
813 notdone=1;type_qualifiers|=XSIGNED;
814 }else if(!strcmp("auto",ctok->name)){
815 next_token();
816 dsc;storage_class=AUTO;notdone=1;
817 }else if(!strcmp("register",ctok->name)){
818#ifdef HAVE_MISRA
819/* removed */
820#endif
821 next_token();
822 dsc;storage_class=REGISTER;notdone=1;
823 }else if(!strcmp("static",ctok->name)){
824 next_token();
825 dsc;storage_class=STATIC;notdone=1;
826#ifdef HAVE_ECPP
827/* removed */
828#endif
829 }else if(!strcmp("extern",ctok->name)){
830 next_token();
831 dsc;storage_class=EXTERN;notdone=1;
832 }else if(!strcmp("typedef",ctok->name)){
833 next_token();
834 dsc;storage_class=TYPEDEF;notdone=1;
835 }else if(c99&&!strcmp("inline",ctok->name)){
836 next_token();
837 have_inline=1;notdone=1;
838#ifdef HAVE_ECPP
839/* removed */
840/* removed */
841/* removed */
842/* removed */
843/* removed */
844/* removed */
845/* removed */
846#endif
847 }else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__reg",ctok->name)){
848 char *d;
849 next_token();killsp();
850 if(ctok->type==LPAR) next_token(); else error(151);
851 killsp();
852 if(d=get_string()){
853 for(hard_reg=1;hard_reg<=MAXR;hard_reg++){
854 if(!strcmp(d,regnames[hard_reg])) break;
855 }
856 if(hard_reg>MAXR){ hard_reg=0;error(220,d);}
857 notdone=1;
858 free(d);
859 }
860 killsp();
861 if(ctok->type==RPAR) next_token(); else error(59);
862 killsp();
863 }else if(!strcmp("__mask",ctok->name)){
864 np tree;
865 next_token();killsp();
866 if(ctok->type==LPAR) next_token(); else error(151);
867 tree=expression();
868 if(tree&&type_expression(tree,0)){
869 if(tree->flags==CEXPR&&ISINT(tree->ntyp->flags)){
870 eval_const(&tree->val,tree->ntyp->flags);
871 mask=vumax;
872 }else
873 error(18);
874 free_expression(tree);
875 }else
876 error(18);
877 killsp();
878 if(ctok->type==RPAR) next_token(); else error(59);
879 killsp();
880 notdone=1;
881 }else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__attr",ctok->name)){
882 char *d;
883 next_token();killsp();
884 if(ctok->type==LPAR) next_token(); else error(151);
885 killsp();
886 if(d=get_string()){
887 if(!attr){
888 attr=d;
889 }else{
890 attr=myrealloc(attr,strlen(attr)+strlen(d)+2);
891 strcat(attr,";");
892 strcat(attr,d);
893 free(d);
894 }
895 notdone=1;
896 }
897 killsp();
898 if(ctok->type==RPAR) next_token(); else error(59);
899 killsp();
900 }else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__vattr",ctok->name)){
901 char *d;
902 next_token();killsp();
903 if(ctok->type==LPAR) next_token(); else error(151);
904 killsp();
905 if(d=get_string()){
906 if(!vattr){
907 vattr=d;
908 }else{
909 vattr=myrealloc(vattr,strlen(vattr)+strlen(d)+2);
910 strcat(vattr,";");
911 strcat(vattr,d);
912 free(d);
913 }
914 notdone=1;
915 }
916 killsp();
917 if(ctok->type==RPAR) next_token(); else error(59);
918 killsp();
919 }else{
920#ifdef HAVE_TARGET_ATTRIBUTES
921 int i;
922 for(i=0;g_attr_name[i];i++){
923 if(!strcmp(g_attr_name[i],ctok->name)){
924 if(tattr&(1L<<i)) error(227,ctok->name);
925 tattr|=(1L<<i);
926 next_token();
927 notdone=1;break;
928 }
929 }
930#endif
931 if(!notdone&&typ==0&&!(type_qualifiers&(XSIGNED|UNSIGNED))){
932 v=find_var(ctok->name,0);
933 if(v&&v->storage_class==TYPEDEF){
934 free(new);
935 new=clone_typ(v->vtyp);
936 typ=settyp(new->flags,typ);
937 notdone=1;
938 next_token();
939 }
940#ifdef HAVE_ECPP
941/* removed */
942/* removed */
943/* removed */
944/* removed */
945/* removed */
946/* removed */
947/* removed */
948/* removed */
949/* removed */
950/* removed */
951/* removed */
952/* removed */
953/* removed */
954/* removed */
955/* removed */
956/* removed */
957/* removed */
958/* removed */
959/* removed */
960/* removed */
961/* removed */
962/* removed */
963/* removed */
964/* removed */
965/* removed */
966/* removed */
967/* removed */
968/* removed */
969/* removed */
970/* removed */
971/* removed */
972/* removed */
973/* removed */
974/* removed */
975/* removed */
976/* removed */
977/* removed */
978/* removed */
979/* removed */
980/* removed */
981/* removed */
982/* removed */
983/* removed */
984/* removed */
985/* removed */
986/* removed */
987#endif
988 }
989 }
990 }
991#ifdef HAVE_ECPP
992/* removed */
993/* removed */
994/* removed */
995/* removed */
996/* removed */
997/* removed */
998/* removed */
999/* removed */
1000/* removed */
1001/* removed */
1002/* removed */
1003#endif
1004 if(DEBUG&2) printf("typ:%d\n",typ);
1005 }while(notdone);
1006 killsp();
1007 return_sc=storage_class;
1008 return_reg=hard_reg;
1009 return_vattr=vattr;
1010 return_mask=mask;
1011 return_inline=have_inline;
1012#ifdef HAVE_ECPP
1013/* removed */
1014/* removed */
1015/* removed */
1016/* removed */
1017#endif
1018#ifdef HAVE_TARGET_ATTRIBUTES
1019 return_tattr=tattr;
1020#endif
1021 if(typ==0){
1022 if(storage_class==0&&type_qualifiers==0&&!hard_reg){
1023 free(new);
1024 return 0;
1025 }
1026#ifdef HAVE_MISRA
1027/* removed */
1028#endif
1029 typ=INT;
1030 }
1031 if(type_qualifiers&(XSIGNED|UNSIGNED))
1032 if(!ISINT(typ))
1033 error(58);
1034 new->flags=typ|type_qualifiers;
1035 new->attr=attr;
1036 return new;
1037}
1038
1039type *declarator(type *a)
1040/* Erzeugt einen neuen Typ, auf Basis des Typs a. */
1041/* a wird hiermit verkettet. */
1042{
1043 type *t;
1044 killsp();*ident=0;
1045 t=direct_declarator(pointer(a));
1046 if(!a)
1047 {if(t) freetyp(t);return 0;}
1048#ifdef HAVE_ECPP
1049/* removed */
1050#endif
1051#ifdef HAVE_EXT_TYPES
1052 conv_typ(t);
1053#endif
1054 return t;
1055}
1056type *pointer(type *a)
1057/* Unterroutine fuer declarator(), behandelt Zeiger auf Typ. */
1058{
1059 type *t;char *attr;int notdone;
1060 if(!a) return(0);
1061 killsp();
1062 while(ctok->type==STAR){
1063 next_token();
1064 t=new_typ();
1065 t->flags=POINTER_TYPE(a);
1066 t->next=a;
1067 attr=0;
1068 a=t;
1069 do{
1070 killsp();
1071 notdone=0;
1072 if(ctok->type==NAME&&!strcmp("const",ctok->name)){
1073 a->flags|=CONST;
1074 notdone=1;
1075 next_token();
1076 }else if(ctok->type==NAME&&!strcmp("volatile",ctok->name)){
1077 a->flags|=VOLATILE;
1078 notdone=1;
1079 next_token();
1080 }else if(c99&&ctok->type==NAME&&!strcmp("restrict",ctok->name)){
1081 a->flags|=RESTRICT;
1082 notdone=1;
1083 next_token();
1084 }else if(ctok->type==NAME&&!strcmp("__attr",ctok->name)){
1085 char *d;
1086 next_token();
1087 killsp();
1088 if(ctok->type==LPAR) next_token(); else error(151);
1089 killsp();
1090 if(d=get_string()){
1091 if(!attr){
1092 attr=d;
1093 }else{
1094 attr=myrealloc(attr,strlen(attr)+strlen(d)+2);
1095 strcat(attr,";");
1096 strcat(attr,d);
1097 free(d);
1098 }
1099 notdone=1;
1100 }
1101 killsp();
1102 if(ctok->type==RPAR) next_token(); else error(59);
1103 killsp();
1104 }
1105 }while(notdone);
1106 a->attr=attr;
1107 }
1108 return a;
1109}
1110type *direct_declarator(type *a)
1111/* Unterroutine zu declarator() */
1112/* behandelt [],(funkt),(dekl). */
1113{
1114 type *rek=0,*merk,*p,*t=0,*first,*last=0;
1115 struct_declaration *fsd;
1116 struct_list (*sl)[];
1117 size_t slsz;char *imerk;
1118 char fbuff[MAXI];
1119 killsp();
1120 if(ctok->type!=NAME&&ctok->type!=LPAR&&ctok->type!=LBRK)
1121 return a;
1122 if(ctok->type==NAME){
1123 cpbez(ident,1);
1124 next_token();
1125 if(!a) return(0);
1126#ifdef HAVE_ECPP
1127/* removed */
1128/* removed */
1129/* removed */
1130/* removed */
1131/* removed */
1132#endif
1133 }
1134 else if(ctok->type==LPAR&&a){
1135 /* Rekursion */
1136 token mtok;
1137 copy_token(&mtok,ctok);
1138 next_token(); killsp();
1139 if(ctok->type!=RPAR&&*ident==0&&!declaration(0)){
1140 merk=a;
1141 rek=declarator(a);
1142 if(ctok->type!=RPAR) error(59); else next_token();
1143 }else
1144
1145 push_token(&mtok);
1146 free(mtok.name);
1147 }
1148 if(!a)return(0);
1149 killsp();
1150 while(ctok->type==LBRK||ctok->type==LPAR){
1151 if(ctok->type==LBRK){
1152 next_token();
1153 killsp();
1154 p=new_typ();
1155 p->flags=ARRAY;
1156 p->next=0;
1157 if(ctok->type==RBRK){
1158 p->size=l2zm(0L);
1159 }else{
1160 np tree;
1161 tree=expression();
1162 if(!type_expression(tree,0)){
1163 /* error("incorrect constant expression");*/
1164 }else{
1165 if(tree->sidefx&&!c99) error(60);
1166 if(tree->flags!=CEXPR||!ISINT(tree->ntyp->flags)){
1167 if(!c99||!ALLOCVLA_INLINEASM)
1168 error(19);
1169 else{
1170 type *st;IC *new;
1171 st=new_typ();
1172 st->flags=HAVE_INT_SIZET?(UNSIGNED|INT):(UNSIGNED|LONG);
1173 p->dsize=add_tmp_var(st);
1174 gen_IC(tree,0,0);
1175 convert(tree,st->flags);
1176 new=new_IC();
1177 new->code=ASSIGN;
1178 new->typf=st->flags;
1179 new->q1=tree->o;
1180 new->z.flags=VAR;
1181 new->z.v=p->dsize;
1182 new->z.val.vmax=l2zm(0L);
1183 new->q2.val.vmax=szof(st);
1184 add_IC(new);
1185 }
1186 }else{
1187 eval_constn(tree);
1188 p->size=vmax;
1189 if(zmleq(p->size,l2zm(0L))) {error(61);p->size=l2zm(1L);}
1190 }
1191 }
1192 free_expression(tree);
1193 }
1194 if(ctok->type!=RBRK) error(62); else next_token();
1195 if(last){
1196 last->next=p;
1197 last=p;
1198 }else{
1199 first=last=p;
1200 }
1201 }
1202#ifdef HAVE_ECPP
1203/* removed */
1204/* removed */
1205/* removed */
1206/* removed */
1207#endif
1208 if(ctok->type==LPAR){
1209 int komma,firstparm,oldstyle=0;
1210#if 0 /*#ifdef HAVE_REGPARMS*/
1211 treg_handle reg_handle=empty_reg_handle;
1212 type rpointer={0};
1213 if(!ffreturn(a)&&(a->flags&NQ)!=VOID){
1214 rpointer.flags=POINTER_TYPE(a);
1215 rpointer.next=a;
1216 reg_parm(&reg_handle,&rpointer,0,a); /*TODO: a might be incomplete */
1217 }
1218#endif
1219#ifdef HAVE_MISRA
1220/* removed */
1221/* removed */
1222#endif
1223 next_token();
1224 killsp();
1225#ifdef HAVE_MISRA
1226/* removed */
1227#endif
1228 fsd=mymalloc(sizeof(*fsd));
1229 slsz=SLSIZE;
1230 sl=mymalloc(sizeof(struct_list)*slsz);
1231 fsd->count=0;
1232 imerk=ident;komma=0;
1233 enter_block();
1234 firstparm=1;
1235 while(ctok->type!=RPAR&&ctok->type!=MDOTS){
1236 int hard_reg;
1237#ifdef HAVE_ECPP
1238/* removed */
1239#endif
1240 if(!firstparm&&!komma) error(57);
1241 komma=firstparm=0;
1242 ident=fbuff;*fbuff=0;
1243 t=declaration_specifiers();
1244 hard_reg=return_reg;
1245 t=declarator(t);
1246 if(!t){
1247 oldstyle=1;
1248 if(*ident==0) {error(20);freetyp(t);continue;}
1249 }
1250 if(fsd->count){
1251 if((t&&!(*sl)[fsd->count-1].styp)||
1252 (!t&&(*sl)[fsd->count-1].styp))
1253 error(63);
1254 }
1255#ifdef HAVE_ECPP
1256/* removed */
1257/* removed */
1258/* removed */
1259/* removed */
1260/* removed */
1261/* removed */
1262/* removed */
1263/* removed */
1264#endif
1265 if(!return_sc) return_sc=AUTO;
1266 if(return_sc!=AUTO&&return_sc!=REGISTER)
1267 {error(21);return_sc=AUTO;}
1268 (*sl)[fsd->count].styp=t;
1269 (*sl)[fsd->count].storage_class=return_sc;
1270 {
1271 int m=nesting;
1272 nesting=0;
1273 (*sl)[fsd->count].identifier=add_identifier(ident,strlen(ident));
1274 nesting=m;
1275 }
1276 if(t){
1277 if(((*sl)[fsd->count].styp->flags&NQ)==VOID&&fsd->count!=0)
1278 error(22);
1279 /* Arrays in Zeiger umwandeln */
1280 if(ISARRAY((*sl)[fsd->count].styp->flags))
1281 (*sl)[fsd->count].styp->flags=POINTER_TYPE((*sl)[fsd->count].styp->next);
1282 /* Funktionen in Zeiger auf Funktionen umwandeln */
1283 if(ISFUNC((*sl)[fsd->count].styp->flags)){
1284 type *new;
1285 new=new_typ();
1286 new->next=(*sl)[fsd->count].styp;
1287 new->flags=POINTER_TYPE(new->next);
1288 (*sl)[fsd->count].styp=new;
1289 }
1290 }
1291 if(hard_reg&&regok(hard_reg,t->flags,-1)<=0) error(217,regnames[hard_reg]);
1292#if 0 /*#ifdef HAVE_REGPARMS*/
1293 if(t) (*sl)[fsd->count].reg=reg_parm(&reg_handle,t,0,a); /*TODO: a might be incomplete */
1294 if(hard_reg) (*sl)[fsd->count].reg=hard_reg;
1295#else
1296 (*sl)[fsd->count].reg=hard_reg;
1297#endif
1298 fsd->count++;
1299 if(fsd->count>=slsz-2){ /* eins Reserve fuer VOID */
1300 slsz+=SLSIZE;
1301 sl=myrealloc(sl,slsz*sizeof(struct_list));
1302 }
1303 killsp(); /* Hier Syntaxpruefung strenger machen */
1304 if(ctok->type==COMMA) {next_token();komma=1; killsp();}
1305 }
1306 ident=imerk;
1307#ifdef HAVE_MISRA
1308/* removed */
1309#endif
1310 if(ctok->type!=MDOTS||!komma){
1311 int ecpp_addvoid=0;
1312#ifdef HAVE_ECPP
1313/* removed */
1314#endif
1315 if(ecpp_addvoid||(!ecpp&&fsd->count>0&&(!(*sl)[fsd->count-1].styp||((*sl)[fsd->count-1].styp->flags&NQ)!=VOID))){
1316 (*sl)[fsd->count].styp=new_typ();
1317 (*sl)[fsd->count].styp->flags=VOID;
1318 (*sl)[fsd->count].styp->next=0;
1319 (*sl)[fsd->count].reg=0;
1320 (*sl)[fsd->count].identifier=empty;
1321#ifdef HAVE_ECPP
1322/* removed */
1323#endif
1324 fsd->count++;
1325 }
1326 if(ecpp&&ctok->type==MDOTS){next_token();killsp();}
1327 }else if(komma){
1328 next_token();komma=0;
1329 if(oldstyle) error(221);
1330 }
1331 p=new_typ();
1332 p->flags=FUNKT;
1333 {
1334 int m=nesting;
1335 nesting=0;
1336 p->exact=add_sd(fsd,FUNKT);
1337 add_sl(fsd,sl);
1338 free(sl);
1339 nesting=m;
1340 }
1341#ifdef HAVE_REGPARMS
1342 {
1343 treg_handle reg_handle=empty_reg_handle;
1344 int i,r;
1345
1346 p->next=a;
1347
1348 if(!ffreturn(a)&&(a->flags&NQ)!=VOID){
1349 type rpointer={0};
1350
1351 rpointer.flags=POINTER_TYPE(a);
1352 rpointer.next=a;
1353 reg_parm(&reg_handle,&rpointer,0,p);
1354 }
1355
1356 for(i=0;i<p->exact->count;i++){
1357 if((*p->exact->sl)[i].styp)
1358 r=reg_parm(&reg_handle,(*p->exact->sl)[i].styp,0,p);
1359 else
1360 r=0;
1361 if((*p->exact->sl)[i].reg==0) (*p->exact->sl)[i].reg=r;
1362 }
1363 }
1364#endif
1365 killsp();
1366 if(komma) error(59);
1367 if(ctok->type!=RPAR) error(59); else next_token();
1368 killsp();
1369 if(ctok->type==COMMA||ctok->type==SEMIC||ctok->type==RPAR||ctok->type==ASGN)
1370 leave_block();
1371 if(last){
1372 last->next=p;
1373 last=p;
1374 }else{
1375 first=last=p;
1376 }
1377 }
1378 killsp();
1379 }
1380 if(last){last->next=a;last=a;a=first;}
1381 if(rek!=0&&rek!=merk){
1382 /* Zweite Liste anhaengen */
1383 p=rek;
1384 while(p->next!=merk) p=p->next;
1385 if(p) p->next=a; else ierror(0);
1386 return rek;
1387 }
1388 return a;
1389}
1390int declaration(int offset)
1391/* Testet, ob eine Typangabe kommt. Wenn offset!=0 ist, */
1392/* muss s auf '(' zeigen und es wird getestet, ob nach der */
1393/* Klammer eine Typangabe kommt. */
1394/* In jedem Fall zeigt s danach wieder auf dieselbe Stelle */
1395/* im Source. */
1396{
1397 Var *v;token mtok;
1398 int fl=0;
1399 if(offset){
1400 copy_token(&mtok,ctok);
1401 next_token();
1402 killsp();
1403 }
1404 if(ctok->type==NAME){
1405 if(!strcmp("auto",ctok->name)) fl=1;
1406 else if(!strcmp("char",ctok->name)) fl=1;
1407 else if(!strcmp("const",ctok->name)) fl=1;
1408 else if(!strcmp("double",ctok->name)) fl=1;
1409 else if(!strcmp("enum",ctok->name)) fl=1;
1410 else if(!strcmp("extern",ctok->name)) fl=1;
1411 else if(!strcmp("float",ctok->name)) fl=1;
1412 else if(!strcmp("int",ctok->name)) fl=1;
1413 else if(!strcmp("long",ctok->name)) fl=1;
1414 else if(!strcmp("register",ctok->name)) fl=1;
1415 else if(c99&&!strcmp("restrict",ctok->name)) fl=1;
1416 else if(!strcmp("short",ctok->name)) fl=1;
1417 else if(!strcmp("signed",ctok->name)) fl=1;
1418 else if(!strcmp("static",ctok->name)) fl=1;
1419 else if(!strcmp("struct",ctok->name)) fl=1;
1420 else if(!strcmp("typedef",ctok->name)) fl=1;
1421 else if(!strcmp("union",ctok->name)) fl=1;
1422 else if(!strcmp("unsigned",ctok->name)) fl=1;
1423 else if(!strcmp("void",ctok->name)) fl=1;
1424 else if(!strcmp("volatile",ctok->name)) fl=1;
1425 else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__reg",ctok->name)) fl=1;
1426 else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__attr",ctok->name)) fl=1;
1427 else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__vattr",ctok->name)) fl=1;
1428 else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__mask",ctok->name)) fl=1;
1429 else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__readsmem",ctok->name)) fl=1;
1430 else if(/*!(c_flags[7]&USEDFLAG)&&*/!strcmp("__writesmem",ctok->name)) fl=1;
1431 else{
1432 v=find_var(ctok->name,0);
1433 if(v&&v->storage_class==TYPEDEF) fl=1;
1434 }
1435 }
1436#ifdef HAVE_ECPP
1437/* removed */
1438/* removed */
1439/* removed */
1440/* removed */
1441/* removed */
1442/* removed */
1443#endif
1444 if(offset){
1445 push_token(&mtok);
1446 free(mtok.name);
1447 }
1448 return fl;
1449}
1450void init_sl(struct_list *sl){
1451 if(!sl){ierror(0);return;}
1452 sl->identifier=0;
1453 sl->styp=0;
1454 sl->align=0;
1455 sl->bfoffset=-1;
1456 sl->bfsize=-1;
1457 sl->reg=0;
1458 sl->storage_class=0;
1459#ifdef HAVE_ECPP
1460/* removed */
1461#endif
1462}
1463void add_sl(struct_declaration *sd,struct_list (*sl)[])
1464/* Fuegt ein struct_list-Array in eine struct_declaration ein. */
1465/* Das Array muss mind. sd->count Elements haben und wird kopiert. */
1466{
1467 size_t sz=sizeof(struct_list)*sd->count;
1468 sd->sl=mymalloc(sz);
1469 memcpy(sd->sl,sl,sz);
1470}
1471struct_declaration *add_sd(struct_declaration *new,int typ)
1472/* Fuegt eine Declaration in Liste ein. */
1473{
1474 new->next=0;
1475 new->label=0;
1476 new->typ=typ;
1477 new->identifier=0;
1478 new->tunit=last_tunit;
1479#ifdef HAVE_ECPP
1480/* removed */
1481/* removed */
1482/* removed */
1483/* removed */
1484/* removed */
1485/* removed */
1486#endif
1487 if(first_sd[nesting]==0){
1488 first_sd[nesting]=last_sd[nesting]=new;
1489 }else{
1490 last_sd[nesting]->next=new;
1491 last_sd[nesting]=new;
1492 }
1493 return new;
1494}
1495void free_sd(struct_declaration *p)
1496/* Gibt eine struct_declaration-List inkl. struct_lists und */
1497/* allen Typen jeder struct_list frei, nicht aber identifier. */
1498{
1499 int i;struct_declaration *merk;
1500 while(p){
1501 merk=p->next;
1502 if(p->sl){
1503 for(i=0;i<p->count;i++){
1504 if((*p->sl)[i].styp) freetyp((*p->sl)[i].styp);
1505 }
1506 if(p->count>0) free(p->sl);
1507 }
1508#ifdef HAVE_ECPP
1509/* removed */
1510/* removed */
1511/* removed */
1512#endif
1513 free(p);
1514 p=merk;
1515 }
1516}
1517char *add_identifier(char *identifier,int length)
1518/* Kopiert identifier an sicheren Ort, der spaeter zentral */
1519/* freigegeben werden kann. */
1520/* Sollte noch einbauen, dass ueberprueft wird, ob schon */
1521/* vorhanden und dann nicht zweimal speichern. */
1522{
1523 identifier_list *new;
1524 if((*identifier==0&&length==0)||identifier==empty) return(empty);
1525 new=mymalloc(sizeof(identifier_list));
1526 new->identifier=mymalloc(length+1);
1527 memcpy(new->identifier,identifier,length+1);
1528 new->next=0;new->length=length;
1529 if(last_ilist[nesting]){
1530 last_ilist[nesting]->next=new;
1531 last_ilist[nesting]=new;
1532 }else{
1533 last_ilist[nesting]=first_ilist[nesting]=new;
1534 }
1535 return(new->identifier);
1536}
1537void free_ilist(identifier_list *p)
1538/* Gibt eine verkettete identifier_liste und saemtliche darin */
1539/* gespeicherten Identifier frei. */
1540{
1541 identifier_list *merk;
1542 while(p){
1543 merk=p->next;
1544 if(p->identifier) free(p->identifier);
1545 free(p);
1546 p=merk;
1547 }
1548}
1549int type_uncomplete(type *p)
1550/* Testet, ob Typ unvollstaendig ist. Momentan gelten nur */
1551/* unvollstaendige Strukturen und Arrays von solchen als */
1552/* unvollstaendig, aber keine Zeiger oder Funktionen darauf. */
1553{
1554 struct_declaration *sd;
1555 if(!p){ierror(0);return(0);}
1556 if(ISSTRUCT(p->flags)||ISUNION(p->flags))
1557 if(p->exact->count<=0) return 1;
1558 if(ISARRAY(p->flags)){
1559 if(!p->dsize&&zmleq(p->size,l2zm(0L))) return 1;
1560if(!p->next) ierror(0);
1561 if(type_uncomplete(p->next)) return 1;
1562 }
1563 return 0;
1564}
1565void add_struct_identifier(char *identifier,struct_declaration *sd)
1566/* Erzeugt neuen struct_identifier, fuegt ihn in Liste an und */
1567/* vervollstaendigt unvollstaendige Typen dieser Struktur. */
1568{
1569 struct_identifier *new;
1570/* type *t;*/
1571 if(DEBUG&1) printf("add_si %s (nesting=%d)->%p\n",identifier,nesting,(void *)sd);
1572#ifdef HAVE_MISRA
1573/* removed */
1574/* removed */
1575/* removed */
1576/* removed */
1577/* removed */
1578#endif
1579 new=mymalloc(sizeof(struct_identifier));
1580 new->identifier=add_identifier(identifier,strlen(identifier));
1581 new->sd=sd;
1582 new->next=0;
1583 if(first_si[nesting]==0){
1584 first_si[nesting]=new;last_si[nesting]=new;
1585 }else{
1586 last_si[nesting]->next=new;last_si[nesting]=new;
1587 }
1588 sd->identifier=new->identifier;
1589}
1590void free_si(struct_identifier *p)
1591/* Gibt eine struct_identifier-Liste frei, aber nicht die */
1592/* identifiers und struct_declarations. */
1593{
1594 struct_identifier *merk;
1595 while(p){
1596 merk=p->next;
1597 p->sd->identifier="<prototype-only>";
1598 free(p);
1599 p=merk;
1600 }
1601}
1602struct_declaration *find_struct(char *identifier,int endnesting)
1603
1604/* Sucht angegebene Strukturdefinition und liefert */
1605/* entsprechende struct_declaration. */
1606{
1607 struct_identifier *si; int i,l;
1608 if(misracheck) l=strlen(identifier);
1609 for(i=nesting;i>=endnesting;i--){
1610 si=first_si[i];
1611 while(si){
1612 if(!strcmp(si->identifier,identifier)){
1613 if(DEBUG&1) printf("found tag <%s> at nesting %d->%p\n",identifier,i,(void *)si->sd);
1614 return(si->sd);
1615 }
1616#ifdef HAVE_MISRA
1617/* removed */
1618/* removed */
1619/* removed */
1620/* removed */
1621#endif
1622 si=si->next;
1623 }
1624 }
1625 if(DEBUG&1) printf("didn't find tag <%s>\n",identifier);
1626 return(0);
1627}
1628
1629/* generate code to create a variable-lenght-array */
1630static void create_allocvl(Var *v)
1631{
1632 np tree,ds;
1633 IC *new;Var *fv;
1634
1635 /* check if we got a frame-pointer */
1636 if(FPVLA_REG&&!regsa[FPVLA_REG]){
1637 if(regused[FPVLA_REG])
1638 ierror(0);
1639 else
1640 regsa[FPVLA_REG]=regscratch[FPVLA_REG]=regused[FPVLA_REG]=1;
1641 }
1642
1643 /* if this is the first vla in this block, save old sp */
1644 if(!block_vla[nesting]){
1645 /* declare function - may be done by the backend, if necessary */
1646 if(!(fv=find_ext_var("__oldvlasp"))){
1647 type *t;
1648 static type voidt={VOID};
1649 struct_declaration *sd=mymalloc(sizeof(*sd));
1650 t=new_typ();
1651 t->flags=FUNKT;
1652
1653 t->next=new_typ();
1654 t->next->flags=POINTER_TYPE(&voidt);
1655 t->next->next=clone_typ(&voidt);
1656 sd->count=0;
1657 t->exact=add_sd(sd,FUNKT);
1658 fv=add_var("__oldvlasp",t,EXTERN,0);
1659 fv->fi=new_fi();
1660 fv->fi->flags|=(ALL_USES|ALL_MODS);
1661 fv->fi->inline_asm=mystrdup(OLDSPVLA_INLINEASM);
1662 }
1663 block_vla[nesting]=add_tmp_var(clone_typ(fv->vtyp->next));
1664 tree=gen_libcall("__oldvlasp",0,0,0,0);
1665 new=new_IC();
1666 new->code=ASSIGN;
1667 new->z.flags=VAR;
1668 new->z.v=block_vla[nesting];
1669 new->z.val.vmax=l2zm(0L);
1670 new->q1=tree->o;
1671 new->q2.flags=0;
1672 new->typf=block_vla[nesting]->vtyp->flags;
1673 new->q2.val.vmax=sizetab[new->typf];
1674 add_IC(new);
1675 free_expression(tree);
1676 }
1677
1678 /* make room on the stack */
1679 ds=new_node();
1680 ds->flags=IDENTIFIER;
1681 ds->identifier=empty;
1682 ds->dsize=vlength_szof(v->vtyp);
1683 ds->val.vmax=l2zm(0L);
1684 ds->ntyp=clone_typ(ds->dsize->vtyp);
1685 ds->o.flags=VAR;
1686 ds->o.v=ds->dsize;
1687 ds->o.val.vmax=l2zm(0L);
1688 ds->left=ds->right=0;
1689
1690 if(!find_ext_var("__allocvla")){
1691 /* declare function */
1692 struct_declaration *sd=mymalloc(sizeof(*sd));
1693 type *t=new_typ();
1694 sd->count=1;
1695 sd->sl=mymalloc(sizeof(struct_list));
1696 (*sd->sl)[0].storage_class=AUTO;
1697 (*sd->sl)[0].styp=clone_typ(ds->dsize->vtyp);
1698 (*sd->sl)[0].reg=ALLOCVLA_REG;
1699 t->flags=FUNKT;
1700 t->exact=add_sd(sd,FUNKT);
1701 t->next=new_typ();
1702 t->next->flags=POINTER_TYPE(v->vtyp);
1703 t->next->next=new_typ();
1704 t->next->next->flags=v->vtyp->flags;
1705 fv=add_var("__allocvla",t,EXTERN,0);
1706 fv->fi=new_fi();
1707 fv->fi->flags|=(ALL_USES|ALL_MODS);
1708 fv->fi->inline_asm=mystrdup(ALLOCVLA_INLINEASM);
1709 }
1710
1711 if(!type_expression(ds,0)) ierror(0);
1712 tree=gen_libcall("__allocvla",ds,0,0,0);
1713 new=new_IC();
1714 new->code=ASSIGN;
1715 new->z.flags=VAR;
1716 new->z.v=v;
1717 new->z.val.vmax=l2zm(0L);
1718 new->q1=tree->o;
1719 new->q2.flags=0;
1720 new->typf=POINTER_TYPE(v->vtyp);
1721 new->q2.val.vmax=sizetab[new->typf];
1722 add_IC(new);
1723 free_expression(tree);
1724 vlas=1;
1725}
1726
1727/* reset sp to remove variable-length-arrays */
1728void freevl(void)
1729{
1730 np tree,ds;
1731 Var *fv;
1732 dontdelete=1; /* never remove them, otherwise, fix_vla_jump get confused */
1733 if(!find_ext_var("__resetvlasp")){
1734 struct_declaration *sd=mymalloc(sizeof(*sd));
1735 type *t=new_typ();
1736 sd->count=1;
1737 sd->sl=mymalloc(sizeof(struct_list));
1738 (*sd->sl)[0].storage_class=AUTO;
1739 (*sd->sl)[0].styp=clone_typ(block_vla[nesting]->vtyp);
1740 (*sd->sl)[0].reg=FREEVLA_REG;
1741 t->flags=FUNKT;
1742 t->exact=add_sd(sd,FUNKT);
1743 t->next=new_typ();
1744 t->next->flags=VOID;
1745 fv=add_var("__resetvlasp",t,EXTERN,0);
1746 fv->fi=new_fi();
1747 fv->fi->flags|=(ALL_USES|ALL_MODS);
1748 fv->fi->inline_asm=mystrdup(FREEVLA_INLINEASM);
1749 }
1750 if(nesting==1){
1751 clear_main_ret();
1752 gen_label(return_label);
1753 did_return_label=1;
1754 }
1755 ds=new_node();
1756 ds->flags=IDENTIFIER;
1757 ds->identifier=empty;
1758 ds->dsize=block_vla[nesting];
1759 ds->val.vmax=l2zm(0L);
1760 ds->ntyp=clone_typ(ds->dsize->vtyp);
1761 ds->left=ds->right=0;
1762 ds->o.flags=VAR;
1763 ds->o.v=ds->dsize;
1764 ds->o.val.vmax=l2zm(0L);
1765 if(!type_expression(ds,0)) ierror(0);
1766 tree=gen_libcall("__resetvlasp",ds,0,0,0);
1767 free_expression(tree);
1768 dontdelete=0;
1769}
1770
1771void clearvl(void)
1772{
1773 llist *p,*n;
1774 vlaadjust_list *vl,*vn;
1775 /* look for stack-adjusts that have to be removed */
1776 vl=vlaadjusts[nesting];
1777 while(vl){
1778 int ln;
1779 IC *ic=vl->branch;
1780 if(ic){
1781 ln=ic->typf;
1782 if(ic->code!=BRA) ierror(0);
1783 p=vladeflabels[nesting];
1784 while(p){
1785 if(p->label==ln) break;
1786 p=p->next;
1787 }
1788 if(!p){
1789 ic=ic->prev;
1790 while(ic!=vl->first->prev){
1791 if(!ic) ierror(0);
1792 ic->code=NOP;
1793 ic->q1.flags=ic->q2.flags=ic->z.flags=0;
1794 ic=ic->prev;
1795 }
1796 }
1797 }
1798 vn=vl->next;
1799 free(vl);
1800 vl=vn;
1801 }
1802 freevl();
1803 block_vla[nesting]=0;
1804 p=vladeflabels[nesting];
1805 while(p){
1806 n=p->next;
1807 free(p);
1808 p=n;
1809 }
1810 p=vlajmplabels[nesting];
1811 while(p){
1812 n=p->next;
1813 free(p);
1814 p=n;
1815 }
1816 vladeflabels[nesting]=vlajmplabels[nesting]=0;
1817 vlaadjusts[nesting]=0;
1818}
1819
1820/* Handle a stack of stored sp variables when traversing an IC list; */
1821void vla_nesting(IC *p,Var **vn,int *nest)
1822{
1823 if(p->code==CALL&&(p->q1.flags&(VAR|DREFOBJ))==VAR&&!strcmp(p->q1.v->identifier,"__oldvlasp")){
1824 IC *p2=p->next;
1825 while(p2&&(p2->code==ALLOCREG||p2->code==FREEREG)) p2=p2->next;
1826 if(!p2||p2->code!=GETRETURN||(p2->z.flags&(VAR|DREFOBJ))!=VAR) ierror(0);
1827 /*printf("found save sp to %p\n",p2->z.v);*/
1828 vn[*nest]=p2->z.v;
1829 (*nest)++;
1830 vn[*nest]=0;
1831 if(*nest>=MAXN) ierror(0);
1832 return;
1833 }
1834 if(p->code==CALL&&(p->q1.flags&(VAR|DREFOBJ))==VAR&&!strcmp(p->q1.v->identifier,"__resetvlasp")){
1835 /*printf("found reset\n");*/
1836 if(*nest<=0) ierror(0);
1837 (*nest)--;
1838 return;
1839 }
1840}
1841
1842static int return_vla_nest;
1843static Var *return_last_vlasp;
1844
1845/* Find the stack pointer that is needed when jumping to label lab */
1846Var *vla_find_sp(int lab)
1847{
1848 IC *p;int nest=0;
1849 static Var *vn[MAXN];
1850 for(p=first_ic;p;p=p->next){
1851 if(p->code==LABEL&&p->typf==lab){
1852 return_vla_nest=nest;
1853 return_last_vlasp=vn[nest];
1854 if(nest<=0)
1855 return 0;
1856 else
1857 return vn[nest-1];
1858 }
1859 vla_nesting(p,vn,&nest);
1860 }
1861 ierror(0);
1862}
1863
1864void vla_jump_fix(void)
1865{
1866 IC *p;int nest=0;
1867 static Var *vn[MAXN],*savedsp;
1868 if(DEBUG&1) printf("searching for vla-jump-fixes\n");
1869 for(p=first_ic;p;p=p->next){
1870 /*pric2(stdout,p);*/
1871 if(p->code>=BEQ&&p->code<=BRA){
1872 /*printf("jump found\n");*/
1873 p->savedsp=0;
1874 if(1/*nest>0*/){
1875 /*printf("is in vla context!\n");*/
1876 savedsp=vla_find_sp(p->typf);
1877 if(return_vla_nest>nest||(nest>0&&return_vla_nest==nest&&savedsp!=vn[nest-1])){
1878 err_ic=p;
1879 error(351);
1880 }else if(nest==0||savedsp==vn[nest-1]){
1881 /*printf("jump within the same context\n");*/
1882 }else{
1883 if(vn[nest]){
1884 if(DEBUG&1) printf("have to set sp to %p\n",return_last_vlasp);
1885 p->savedsp=return_last_vlasp;
1886 }else{
1887 int ndiff=nest-return_vla_nest-1;
1888 IC *p2;
1889 /*printf("have to search oldsp ndiff=%d\n",ndiff);*/
1890 for(p2=p->prev;p2;p2=p2->prev){
1891 if(p2->code==CALL&&(p2->q1.flags&(VAR|DREFOBJ))==VAR&&!strcmp(p2->q1.v->identifier,"__oldvlasp")){
1892 if(ndiff==0){
1893 /*printf("found savesp\n");*/
1894 p2=p2->next;
1895 while(p2&&(p2->code==ALLOCREG||p2->code==FREEREG)) p2=p2->next;
1896 if(!p2||p2->code!=GETRETURN) ierror(0);
1897 if((p2->z.flags&(VAR|DREFOBJ))!=VAR) ierror(0);
1898 /*printf("found oldsp %p\n",p2->z.v);*/
1899 p->savedsp=p2->z.v;
1900 break;
1901 }
1902 ndiff--;
1903 }
1904 if(p2->code==CALL&&(p2->q1.flags&(VAR|DREFOBJ))==VAR&&!strcmp(p2->q1.v->identifier,"__resetvlasp")){
1905 ndiff++;
1906 }
1907 }
1908 if(!p2) ierror(0);
1909 }
1910 }
1911 }else{
1912 /*printf("not in vla context\n");*/
1913 }
1914 }
1915 vla_nesting(p,vn,&nest);
1916 }
1917 for(p=first_ic;p;p=p->next){
1918 if(p->code>=BEQ&&p->code<=BRA){
1919 if(p->savedsp){
1920 IC *merkfic,*merklic,*newcode,*m,*new,*setr=0;
1921 np ds,tree;
1922 if(DEBUG&1) printf("generating sp-adjust\n");
1923 merkfic=first_ic;merklic=last_ic;
1924 first_ic=0;last_ic=0;
1925 ds=new_node();
1926 ds->flags=IDENTIFIER;
1927 ds->identifier=empty;
1928 ds->dsize=p->savedsp;
1929 ds->val.vmax=l2zm(0L);
1930 ds->ntyp=clone_typ(ds->dsize->vtyp);
1931 ds->left=ds->right=0;
1932 ds->o.flags=VAR;
1933 ds->o.v=ds->dsize;
1934 ds->o.val.vmax=l2zm(0L);
1935 if(!type_expression(ds,0)) ierror(0);
1936 tree=gen_libcall("__resetvlasp",ds,0,0,0);
1937 free_expression(tree);
1938 newcode=first_ic;
1939 first_ic=merkfic;last_ic=merklic;
1940 if(p->code==BRA){
1941 /* check if the branch was preceded by a SETRETURN */
1942 IC *p2=p->prev;
1943 while(p2&&(p2->code==FREEREG||p2->code==ALLOCREG))
1944 p2=p2->prev;
1945 if(p2->code==SETRETURN&&p2->z.reg)
1946 setr=p2;
1947 }else{
1948 new=new_IC();
1949 new->typf=++label;
1950 if(p->code==BEQ) new->code=BRA;
1951 else if(p->code==BNE) new->code=BEQ;
1952 else if(p->code==BLT) new->code=BGE;
1953 else if(p->code==BGT) new->code=BLE;
1954 else if(p->code==BLE) new->code=BGT;
1955 else if(p->code==BGE) new->code=BLT;
1956 insert_IC(p->prev,new);
1957 }
1958 while(newcode){
1959 m=newcode->next;
1960 insert_IC(p->prev,newcode);
1961 newcode=m;
1962 }
1963 if(p->code!=BRA){
1964 p->code=BRA;
1965 new=new_IC();
1966 new->code=LABEL;
1967 new->typf=label;
1968 insert_IC(p,new);
1969 }
1970 if(setr){
1971 /* save the return value to save it from being overwritten */
1972 /* could be optimized further */
1973 Var *v;
1974 if(ISSCALAR(setr->typf)){
1975 static type t={0};
1976 t.flags=setr->typf;
1977 v=add_tmp_var(clone_typ(&t));
1978 }else ierror(0);
1979 new=new_IC();
1980 *new=*setr;
1981 new->q1.flags=VAR;
1982 new->q1.v=v;
1983 new->q1.val.vmax=l2zm(0L);
1984 setr->z=new->q1;
1985 setr->code=ASSIGN;
1986 insert_IC(p->prev,new);
1987 }
1988 }
1989 }
1990 }
1991}
1992
1993
1994Var *add_tmp_var(type *t)
1995{
1996 t->flags&=NU;
1997 return add_var(empty,t,AUTO,0);
1998}
1999Var *add_var(char *identifier, type *t, int storage_class,const_list *clist)
2000/* Fuegt eine Variable mit Typ in die var_list ein. */
2001/* In der storage_class werden die Flags PARAMETER und evtl. */
2002/* OLDSTYLE und REGPARM erkannt. */
2003{
2004 Var *new;int f;
2005 struct_declaration *sd;
2006 static zmax paroffset;
2007 zmax al;
2008 /*if(*identifier==0) return;*/ /* sollte woanders bemaekelt werden */
2009 if(DEBUG&2) printf("add_var(): %s\n",identifier);
2010#ifdef HAVE_TARGET_VARHOOK_PRE
2011 add_var_hook_pre(identifier,t,storage_class,clist);
2012#endif
2013#ifdef HAVE_MISRA
2014/* removed */
2015/* removed */
2016/* removed */
2017/* removed */
2018/* removed */
2019/* removed */
2020#endif
2021 if(ISFUNC(t->flags&NQ)&&(ISARRAY(t->next->flags)||ISFUNC(t->next->flags)))
2022 error(25);
2023 new=mymalloc(sizeof(Var));
2024 if(!*identifier&&identifier!=empty) ierror(0);
2025 new->clist=clist;
2026 new->vtyp=t;
2027 new->storage_class=storage_class&PLAIN_STORAGE_CLASS;
2028 new->reg=0;
2029 new->vattr=0;
2030 new->next=0;
2031 new->flags=0;
2032 new->inr=0;
2033 new->fi=0;
2034 new->nesting=nesting;
2035 new->filename=filename;
2036 new->line=line;
2037 new->dfilename=0;
2038 new->dline=0;
2039 new->description=0;
2040 new->tunit=last_tunit;
2041 new->inline_copy=0;
2042 new->index=-1;
2043#ifdef HAVE_TARGET_ATTRIBUTES
2044 new->tattr=0;
2045#endif
2046 /* if((storage_class&PLAIN_STORAGE_CLASS)==STATIC||(storage_class&PLAIN_STORAGE_CLASS)==EXTERN) new->flags=USEDASSOURCE|USEDASDEST;*/
2047 if(DEBUG&2) printf("storage_class=%d\n",storage_class);
2048 if(storage_class&PARAMETER) new->flags|=USEDASDEST;
2049 if(storage_class&REGPARM){
2050 new->flags|=REGPARM;
2051 if(!(storage_class&DBLPUSH)){
2052 if((storage_class&OLDSTYLE)&&(t->flags&NQ)==FLOAT)
2053 new->flags|=CONVPARAMETER;
2054 storage_class&=~PARAMETER;
2055 }
2056 }
2057 if(DEBUG&2) printf("storage_class=%d\n",storage_class);
2058 if(DEBUG&2) printf("max_offset=%ld\n",zm2l(max_offset));
2059 if(is_vlength(t)&&storage_class!=AUTO&&storage_class!=REGISTER)
2060 error(315);
2061 if((storage_class&PLAIN_STORAGE_CLASS)==REGISTER) new->priority=registerpri; else new->priority=0;
2062 if(/*nesting==0&&*/new->storage_class==EXTERN){
2063 int m=nesting;
2064 nesting=0;
2065 new->identifier=add_identifier(identifier,strlen(identifier));
2066 nesting=m;
2067 if(last_ext){
2068 last_ext->next=new;
2069 last_ext=new;
2070 }else{
2071 first_ext=last_ext=new;
2072 vl0=first_ext;
2073 }
2074 if(hash_ext) add_hashentry(hash_ext,new->identifier,new);
2075 }else{
2076 new->identifier=add_identifier(identifier,strlen(identifier));
2077 if(last_var[nesting]){
2078 new->offset=zmadd(last_var[nesting]->offset,szof(last_var[nesting]->vtyp));
2079 last_var[nesting]->next=new;
2080 last_var[nesting]=new;
2081 }else{
2082 new->offset=l2zm(0L);
2083 paroffset=l2zm(0L);;
2084 first_var[nesting]=last_var[nesting]=new;
2085 if(nesting==0) vl1=new;
2086 if(nesting==1) vl2=new;
2087 }
2088 }
2089 f=t->flags&NQ;
2090 if((storage_class&PLAIN_STORAGE_CLASS)==AUTO||(storage_class&PLAIN_STORAGE_CLASS)==REGISTER){
2091 if(DEBUG&2) printf("auto\n");
2092 al=falign(t);
2093 if((c_flags_val[0].l&2)&&nesting==1&&!(storage_class&PARAMETER)){
2094 new->offset=max_offset;
2095 }else{
2096 if(storage_class&PARAMETER){
2097 new->offset=paroffset;
2098 if(align_arguments)
2099 new->offset=zmmult(zmdiv(zmadd(new->offset,zmsub(al,l2zm(1L))),al),al);
2100 }else{
2101 new->offset=local_offset[nesting];
2102 new->offset=zmmult(zmdiv(zmadd(new->offset,zmsub(al,l2zm(1L))),al),al);
2103 }
2104 }
2105 if(storage_class&PARAMETER){
2106 new->offset=zmmult(zmdiv(zmadd(new->offset,zmsub(stackalign,l2zm(1L))),stackalign),stackalign);
2107 if(ISINT(f)&&f<INT&&!short_push){
2108 /* Integer-Erweiterungen fuer alle Funktionsparameter */
2109 paroffset=zmadd(new->offset,sizetab[INT]);
2110 }else{
2111 if(f==FLOAT&&(storage_class&OLDSTYLE)){
2112 /* Bei alten Funktionen werden FLOAT als DOUBLE uebergeben */
2113 new->offset=zmmult(zmdiv(zmadd(new->offset,zmsub(align[DOUBLE],l2zm(1L))),align[DOUBLE]),align[DOUBLE]);
2114 paroffset=zmadd(new->offset,sizetab[DOUBLE]);
2115 }else{
2116 paroffset=zmadd(new->offset,szof(new->vtyp));
2117 }
2118 }
2119 }else{
2120 local_offset[nesting]=zmadd(new->offset,szof(new->vtyp));
2121 }
2122 if(!(storage_class&PARAMETER))
2123 if(zmleq(max_offset,local_offset[nesting])) max_offset=local_offset[nesting];
2124 if(DEBUG&2) printf("max_offset=%ld\n",zm2l(max_offset));
2125 }
2126 if((storage_class&PLAIN_STORAGE_CLASS)==STATIC) new->offset=l2zm((long)++label);
2127 if(storage_class&PARAMETER){
2128
2129 if(DEBUG&2) printf("parameter\n");
2130
2131 if(ISINT(f)&&f<INT&&!zmleq(sizetab[INT],sizetab[f])){
2132 if(BIGENDIAN){
2133 new->offset=zmadd(new->offset,zmsub(sizetab[INT],sizetab[f]));
2134 }else{
2135 if(!LITTLEENDIAN)
2136 ierror(0);
2137 }
2138 }
2139 if((storage_class&OLDSTYLE)&&f==FLOAT){
2140 /* Bei alten Funktionen werden DOUBLE nach FLOAT konvertiert */
2141 if(!(storage_class&REGPARM)){
2142#if HAVE_LIBCALLS
2143 static type dt={DOUBLE},ft={FLOAT};
2144 static node n,nn;
2145 IC *conv=new_IC();
2146 n.flags=REINTERPRET;
2147 n.left=&nn;
2148 n.ntyp=&dt;
2149 nn.flags=IDENTIFIER;
2150 nn.identifier=identifier;
2151 nn.ntyp=&ft;
2152 nn.o.flags=VAR|DONTREGISTERIZE;
2153 nn.o.v=new;
2154 nn.o.val.vmax=l2zm(0L);
2155 n.o=nn.o;
2156 convert(&n,FLOAT);
2157
2158
2159 conv->code=ASSIGN;
2160 conv->typf=FLOAT;
2161 conv->q1=n.o;
2162 conv->z.v=new;
2163 conv->z.flags=VAR;
2164 conv->z.val.vmax=l2zm(0L);
2165 conv->q2.val.vmax=sizetab[FLOAT];
2166 conv->z.v=new;
2167 add_IC(conv);
2168#else
2169 IC *conv=new_IC();
2170 conv->code=CONVERT;
2171 conv->typf=FLOAT;
2172 conv->typf2=DOUBLE;
2173 conv->q1.flags=VAR|DONTREGISTERIZE;
2174 conv->z.flags=VAR;
2175 conv->q2.flags=0;
2176 conv->q1.v=conv->z.v=new;
2177 conv->q1.val.vmax=conv->z.val.vmax=l2zm(0);
2178 add_IC(conv);
2179#endif
2180 }
2181 new->flags|=CONVPARAMETER;
2182 }
2183 new->offset=zmsub(l2zm(0L),zmadd(maxalign,new->offset));
2184 }
2185 if((storage_class&PLAIN_STORAGE_CLASS)==EXTERN){
2186 if(!strcmp("fprintf",identifier)) new->flags|=PRINTFLIKE;
2187 if(!strcmp("printf",identifier)) new->flags|=PRINTFLIKE;
2188 if(!strcmp("sprintf",identifier)) new->flags|=PRINTFLIKE;
2189 if(!strcmp("fscanf",identifier)) new->flags|=SCANFLIKE;
2190 if(!strcmp("scanf",identifier)) new->flags|=SCANFLIKE;
2191 if(!strcmp("sscanf",identifier)) new->flags|=SCANFLIKE;
2192 }
2193 if(is_vlength(new->vtyp))
2194 create_allocvl(new);
2195#ifdef HAVE_TARGET_VARHOOK_POST
2196 add_var_hook_post(new);
2197#endif
2198 return(new);
2199}
2200void free_var(Var *p)
2201/* Gibt Variablenliste inkl. Typ, aber ohne Identifier frei. */
2202{
2203 Var *merk;
2204 while(p){
2205 if(!*p->identifier&&p->identifier!=empty) ierror(0);
2206 free(p->description);
2207 free(p->vattr);
2208 merk=p->next;
2209 if(!(p->flags&USEDASADR)&&(p->storage_class==AUTO||p->storage_class==REGISTER)){
2210 if(*p->identifier&&!(p->flags&USEDASDEST)&&ISSCALAR(p->vtyp->flags)) error(64,p->identifier);
2211 if(*p->identifier&&!(p->flags&USEDASSOURCE)&&ISSCALAR(p->vtyp->flags)) error(65,p->identifier);
2212 }
2213 if(DEBUG&2) printf("free_var %s, pri=%d\n",p->identifier,p->priority);
2214 if(p->vtyp) freetyp(p->vtyp);
2215 if(p->clist) free_clist(p->clist);
2216 if(p->fi){
2217 if(DEBUG&2) printf("free_fi of function %s\n",p->identifier);
2218 free_fi(p->fi);
2219 if(DEBUG&2) printf("end free_fi of function %s\n",p->identifier);
2220 }
2221 free(p);
2222 p=merk;
2223 }
2224}
2225Var *find_ext_var(char *identifier)
2226{
2227 Var *v;int l;
2228 if(misracheck) l=strlen(identifier);
2229 if(hash_ext) return find_name(hash_ext,identifier);
2230 for(v=first_ext;v;v=v->next){
2231 if(!strcmp(v->identifier,identifier)) return v;
2232#ifdef HAVE_MISRA
2233/* removed */
2234/* removed */
2235/* removed */
2236/* removed */
2237#endif
2238
2239 }
2240 return 0;
2241}
2242Var *find_var(char *identifier,int endnesting)
2243/* Sucht Variable mit Bezeichner und liefert Zeiger zurueck */
2244/* es werden nur Variablen der Bloecke endnesting-nesting */
2245/* durchsucht. */
2246{
2247 int i,l;Var *v;
2248 if(identifier==0||*identifier==0) return 0;
2249 if(misracheck) l=strlen(identifier);
2250 for(i=nesting;i>=endnesting;i--){
2251 for(v=first_var[i];v;v=v->next){
2252 if(!strcmp(v->identifier,identifier))
2253 return v;
2254#ifdef HAVE_MISRA
2255/* removed */
2256/* removed */
2257/* removed */
2258/* removed */
2259#endif
2260 }
2261 }
2262 if(endnesting==0){
2263 v=find_ext_var(identifier);
2264 if(v&&!(v->flags&NOTINTU))
2265 return v;
2266 else
2267 return 0;
2268 }else
2269 return 0;
2270}
2271
2272
2273#ifdef HAVE_MISRA
2274/* removed */
2275/* removed */
2276#endif
2277
2278
2279
2280int check_zero_initialisation(const_list* cl, int typ)
2281{
2282
2283 if (cl->next) return 0;
2284 if (cl->tree) return 0;
2285 if (cl->other) {
2286 return check_zero_initialisation(cl->other,typ);
2287 } else {
2288 eval_const(&cl->val,typ);
2289 if ( (zmeqto(vmax,l2zm(0L))) && (zumeqto(vumax,ul2zum(0UL))) && (zldeqto(vldouble,d2zld(0.0))) ) {
2290 return 1;
2291 }
2292 }
2293 return 0;
2294}
2295
2296/* decide whether a initialization shall be performed only be generated code
2297 or if a table copy should be used first */
2298int use_only_dyn_init(zmax sz,zmax dyn_sz,zmax const_sz,int dyn_cnt,int const_cnt)
2299{
2300 if(zmleq(sz,l2zm(clist_copy_stack)))
2301 return 1;
2302 if(zmeqto(dyn_sz,l2zm(0L)))
2303 return 0;
2304 if(!zmleq(zmdiv(sz,dyn_sz),l2zm(2L)))
2305 return 0;
2306 else
2307 return 1;
2308}
2309
2310void init_local_compound(Var *v)
2311{
2312 if(v->storage_class==AUTO||v->storage_class==REGISTER){
2313 IC *new;
2314 /* Initialisierung von auto-Variablen */
2315 new=new_IC();
2316 new->code=ASSIGN;
2317 new->typf=v->vtyp->flags;
2318 new->q2.flags=0;
2319 new->q2.val.vmax=szof(v->vtyp);
2320 new->z.flags=VAR;
2321 new->z.v=v;
2322 new->z.val.vmax=l2zm(0L);
2323 if(v->clist->tree){
2324 /* einzelner Ausdruck */
2325 gen_IC(v->clist->tree,0,0);
2326 convert(v->clist->tree,v->vtyp->flags&NU);
2327 new->q1=v->clist->tree->o;
2328 add_IC(new);
2329 /* v->clist=0;*/
2330 }else{
2331 /* Array etc. */
2332 Var *nv;
2333 if(!ISSCALAR(v->vtyp->flags)&&!use_only_dyn_init(szof(v->vtyp),init_dyn_sz,init_const_sz,init_dyn_cnt,init_const_cnt)){
2334 nv=add_var(empty,clone_typ(v->vtyp),STATIC,v->clist);
2335 nv->flags|=DEFINED;
2336 nv->dfilename=filename;
2337 nv->dline=line;
2338 nv->vtyp->flags|=CONST;
2339 /* v->clist=0;*/
2340 new->q1.flags=VAR;
2341 new->q1.v=nv;
2342 new->q1.val.vmax=l2zm(0L);
2343
2344 add_IC(new);
2345
2346 dynamic_init(v,v->vtyp,v->clist,0,1);
2347 }else{
2348 dynamic_init(v,v->vtyp,v->clist,0,0);
2349 }
2350 }
2351 }
2352}
2353
2354#ifdef HAVE_MISRA
2355/* removed */
2356/* removed */
2357/* removed */
2358#endif
2359
2360void var_declaration(void)
2361/* Bearbeitet eine Variablendeklaration und erzeugt alle */
2362/* noetigen Strukturen. */
2363{
2364 type *ts,*t,*old=0,*om=0;char *imerk,vident[MAXI];
2365 int mdef=0,makeint=0,notdone,storage_class,msc,extern_flag,isfunc,
2366 had_decl,hard_reg,mhr,diffunit=0,inline_flag;
2367 Var *v;
2368 char *vattr;
2369 zumax mask;
2370 int base_type;
2371#ifdef HAVE_TARGET_ATTRIBUTES
2372 unsigned long tattr;
2373#endif
2374#ifdef HAVE_ECPP
2375/* removed */
2376/* removed */
2377/* removed */
2378/* removed */
2379#endif
2380 ts=declaration_specifiers();notdone=1;
2381
2382 storage_class=return_sc;hard_reg=return_reg;vattr=return_vattr;mask=return_mask;
2383 inline_flag=return_inline;
2384#ifdef HAVE_ECPP
2385/* removed */
2386#endif
2387 if(for_decl&&storage_class!=0&&storage_class!=AUTO&&storage_class!=REGISTER){
2388 error(299);
2389 storage_class=AUTO;
2390 }
2391
2392#ifdef HAVE_TARGET_ATTRIBUTES
2393 tattr=return_tattr;
2394#endif
2395 if(storage_class==EXTERN) extern_flag=1; else extern_flag=0;
2396 killsp();
2397 if(ctok->type==SEMIC){
2398 if(!ts) error(0);
2399 if(storage_class||(!ISSTRUCT(ts->flags)&&!ISUNION(ts->flags)&&(ts->flags&NQ)!=INT))
2400 error(36);
2401 freetyp(ts);
2402 next_token();killsp();
2403 return;
2404 }
2405 if(nesting==0&&(storage_class==AUTO||storage_class==REGISTER))
2406 {error(66);storage_class=EXTERN;}
2407 if(!ts){
2408 if(nesting<=1){
2409 ts=new_typ();
2410 ts->flags=INT;ts->next=0;
2411 makeint=1;
2412 if(!storage_class) storage_class=EXTERN;
2413#ifdef HAVE_MISRA
2414/* removed */
2415#endif
2416 error(67);
2417 }else{
2418 error(365);
2419 }
2420 }
2421 if(storage_class==0){
2422 if(nesting==0)
2423 storage_class=EXTERN;
2424 else
2425 storage_class=AUTO;
2426 }
2427 msc=storage_class;mhr=hard_reg;
2428 while(notdone){
2429 int oldnesting=nesting;
2430 imerk=ident;ident=vident;*vident=0; /* merken von ident hier vermutlich */
2431 storage_class=msc;hard_reg=mhr;
2432 if(old) {freetyp(old);old=0;}
2433 t=declarator(clone_typ(ts));
2434#ifdef HAVE_ECPP
2435/* removed */
2436/* removed */
2437/* removed */
2438/* removed */
2439/* removed */
2440#endif
2441#ifdef HAVE_EXT_TYPES
2442 conv_typ(t);
2443#endif
2444 if(!ISFUNC(t->flags)){
2445 isfunc=0;
2446 if(inline_flag) error(301);
2447 }else{
2448 isfunc=1;
2449#ifdef HAVE_MISRA
2450/* removed */
2451#endif
2452 if(storage_class!=STATIC&&storage_class!=TYPEDEF) storage_class=EXTERN;
2453 }
2454 ident=imerk; /* nicht unbedingt noetig ? */
2455 if(!*vident){
2456 free(ts);free(t);
2457 error(36);return;
2458 }
2459 v=find_var(vident,oldnesting);
2460 if(!v&&/*oldnesting==0&&*/storage_class==EXTERN&&cross_module&&(v=find_ext_var(vident))){
2461 v->flags&=~NOTINTU;
2462 diffunit=1;
2463 /*FIXME: check auf doppelte Def. */
2464 }
2465#ifdef HAVE_MISRA
2466/* removed */
2467/* removed */
2468/* removed */
2469/* removed */
2470/* removed */
2471/* removed */
2472/* removed */
2473/* removed */
2474/* removed */
2475#endif
2476 if(v){
2477 had_decl=1;
2478 if(storage_class==TYPEDEF){
2479 error(226,v->identifier);
2480 }else{
2481 if(nesting>0&&(v->flags&DEFINED)&&!extern_flag&&!isfunc){
2482 error(27,vident);
2483 }else{
2484 if(t&&v->vtyp&&!compatible_types(v->vtyp,t,NU|CONST|VOLATILE)){
2485 if(ISFUNC(t->flags)&&!ISFUNC(v->vtyp->flags))
2486 error(361,vident);
2487 else
2488 error(68,vident);
2489#ifdef HAVE_MISRA
2490/* removed */
2491#endif
2492 }
2493 if((storage_class!=v->storage_class&&!extern_flag)||hard_reg!=v->reg)
2494 error(28,v->identifier);
2495 if(!isfunc&&!extern_flag) v->flags|=TENTATIVE;
2496 }
2497#ifdef HAVE_TARGET_ATTRIBUTES
2498 {
2499 int i;
2500 for(i=0;g_attr_name[i];i++){
2501 if((v->tattr&(1L<<i))!=(tattr&(1L<<i))) error(228,vident,g_attr_name[i]);
2502 }
2503 v->tattr=tattr;
2504 }
2505#endif
2506 if(vattr){
2507 if(!v->vattr||!strstr(v->vattr,vattr)){
2508 error(370,v->identifier,vattr,v->vattr?v->vattr:empty);
2509 add_attr(&v->vattr,vattr);
2510 }
2511 if(ISFUNC(v->vtyp->flags)) fi_from_attr(v);
2512 }
2513 if(!isfunc){
2514 if(!ISARRAY(t->flags)||!zmeqto(t->size,l2zm(0L))){
2515 free(v->vtyp);
2516 v->vtyp=t;
2517 }
2518 }else{
2519 om=v->vtyp;
2520 if(t->exact->count>0){
2521 old=v->vtyp;v->vtyp=t;
2522 }
2523 }
2524 }
2525#ifdef HAVE_TARGET_VARHOOK_POST
2526 add_attr_haddecl=v;
2527 add_var_hook_post(v);
2528 add_attr_haddecl=0;
2529#endif
2530
2531 }else{
2532 had_decl=0;
2533#ifdef HAVE_MISRA
2534/* removed */
2535#endif
2536 if(isfunc&&ctok->type!=COMMA&&ctok->type!=SEMIC&&ctok->type!=RPAR&&ctok->type!=ASGN&&nesting>0) nesting--;
2537 if(!zumeqto(mask,ul2zum(0UL))){
2538 sprintf(vident+strlen(vident),".%lu",zum2ul(mask));
2539 }
2540 v=add_var(vident,t,storage_class,0);
2541#ifdef HAVE_ECPP
2542/* removed */
2543/* removed */
2544/* removed */
2545/* removed */
2546/* removed */
2547/* removed */
2548/* removed */
2549/* removed */
2550/* removed */
2551#endif
2552 v->reg=hard_reg;
2553 if(vattr)
2554 add_attr(&v->vattr,vattr);
2555 if(ISFUNC(v->vtyp->flags))
2556 fi_from_attr(v);
2557#ifdef HAVE_TARGET_ATTRIBUTES
2558 v->tattr=tattr;
2559#endif
2560 if(isfunc&&ctok->type!=COMMA&&ctok->type!=SEMIC&&ctok->type!=RPAR&&ctok->type!=ASGN&&nesting>=0) nesting++;
2561 if(!v) ierror(0);
2562 else{
2563 if(!isfunc&&!extern_flag){
2564 v->flags|=TENTATIVE;
2565 if(nesting>0){
2566 v->flags|=DEFINED;
2567 v->dfilename=filename;
2568 v->dline=line;
2569 }
2570 }
2571 }
2572 om=0;
2573 }
2574 if(isfunc&&inline_flag){
2575 v->flags|=INLINEFUNC;
2576 if(extern_flag) v->flags|=INLINEEXT;
2577 }
2578#ifdef HAVE_MISRA
2579/* removed */
2580/* removed */
2581/* removed */
2582/* removed */
2583/* removed */
2584/* removed */
2585/* removed */
2586/* removed */
2587/* removed */
2588/* removed */
2589/* removed */
2590/* removed */
2591/* removed */
2592/* removed */
2593/* removed */
2594/* removed */
2595/* removed */
2596/* removed */
2597/* removed */
2598/* removed */
2599/* removed */
2600#endif
2601 if(disallow_statics&&v->storage_class==STATIC&&*v->identifier&&!is_const(v->vtyp))
2602 error(302,v->identifier);
2603 killsp();
2604 /* Inline-Assembler-Code in Funktionsdeklarationen */
2605 if(ctok->type==ASGN&&ISFUNC(v->vtyp->flags)&&(header_cnt>0||!(c_flags[7]&USEDFLAG))){
2606 np tree;
2607 next_token();killsp();
2608 if(v->fi){free(v->fi->inline_asm);v->fi->inline_asm=0;}
2609 if(!v->fi) v->fi=new_fi();
2610 v->fi->inline_asm=get_string();
2611 /*STRBACK(v->fi->inline_asm);*/
2612 mdef=1;
2613 }else{
2614 /*if(v->fi){free(v->fi->inline_asm);v->fi->inline_asm=0;}*/
2615 }
2616 /* Initialisierung von Variablen bei Deklaration */
2617 if(ctok->type==ASGN){
2618
2619 next_token();killsp();
2620 if(!had_decl&&v->nesting==0&&v->storage_class==EXTERN&&strcmp("main",v->identifier))
2621 error(168,v->identifier);
2622 if(v->flags&DEFINED){
2623 if(nesting==0) error(30,v->identifier);
2624 }else{
2625 v->flags|=DEFINED;
2626 v->dfilename=filename;
2627 v->dline=line;
2628#ifdef HAVE_MISRA
2629/* removed */
2630/* removed */
2631/* removed */
2632/* removed */
2633/* removed */
2634#endif
2635 }
2636 if(v->storage_class==TYPEDEF) error(114,v->identifier);
2637 if(extern_flag){
2638 if(nesting==0)
2639 error(118,v->identifier);
2640 else
2641 error(207,v->identifier);
2642 if(v->storage_class!=EXTERN){ error(77);v->storage_class=EXTERN;}
2643 }
2644#ifdef HAVE_MISRA
2645/* removed */
2646/* removed */
2647#endif
2648 init_dyn_sz=l2zm(0L);
2649 init_dyn_cnt=0;
2650 init_const_sz=l2zm(0L);
2651 init_const_cnt=0;
2652 v->clist=initialization(v->vtyp,v->storage_class==AUTO||v->storage_class==REGISTER,0,0,0,0);
2653 /* MISRA Rule 9.2 violation checking and error reporting */
2654#ifdef HAVE_MISRA
2655/* removed */
2656/* removed */
2657/* removed */
2658/* removed */
2659/* removed */
2660/* removed */
2661#endif
2662 if(v->clist){
2663 if(ISARRAY(v->vtyp->flags)&&zmeqto(v->vtyp->size,l2zm(0L))){
2664 const_list *p=v->clist;
2665 while(p){v->vtyp->size=zmadd(p->idx,l2zm(1L));p=p->next;}
2666 if(v->storage_class==AUTO||v->storage_class==REGISTER){
2667 local_offset[nesting]=zmadd(local_offset[nesting],szof(v->vtyp));
2668 if(zmleq(max_offset,local_offset[nesting])) max_offset=local_offset[nesting];
2669 }
2670 }
2671 if(v->storage_class==AUTO||v->storage_class==REGISTER){
2672
2673 init_local_compound(v);
2674
2675 }else if(c_flags[19]&USEDFLAG){
2676 /* Ohne Optimierung gleich erzeugen; das ist noch */
2677 /* etwas von der genauen Implementierung der Liste */
2678 /* der Variablen abhaengig. */
2679 Var *merk=v->next;
2680 v->next=0;
2681 gen_vars(v);
2682 v->next=merk;
2683 v->clist=0;
2684 }
2685 }
2686 }else{
2687 if((v->flags&DEFINED)&&type_uncomplete(v->vtyp)) error(202,v->identifier);
2688 if((v->vtyp->flags&CONST)&&(v->storage_class==AUTO||v->storage_class==REGISTER))
2689 error(119,v->identifier);
2690 }
2691 if(ctok->type==COMMA) {next_token();killsp();mdef=1;} else notdone=0;
2692 }
2693 freetyp(ts);
2694
2695 if(ISFUNC(t->flags)&&v->reg)
2696 t->next->reg=v->reg;
2697
2698 if(!mdef&&t&&(t->flags&NQ)==FUNKT&&ctok->type!=SEMIC){
2699 /* Funktionsdefinition*/
2700 int i,oldstyle=0;
2701
2702#ifdef HAVE_MISRA
2703/* removed */
2704/* removed */
2705#endif
2706#ifdef HAVE_REGPARMS
2707 treg_handle reg_handle;
2708#endif
2709 if(DEBUG&1) printf("Funktionsdefinition! %s %p\n",v->identifier,(void *)v);
2710 {
2711 int i;
2712 for(i=1;i<=MAXR;i++) {regs[i]=regused[i]=regsa[i];regsbuf[i]=0;}
2713 }
2714 cur_func=v->identifier;
2715 cur_funcv=v;
2716 if(only_inline==2) only_inline=0;
2717 if(nesting<1) enter_block();
2718 if(nesting>1) error(32);
2719 if(v->flags&DEFINED){
2720 if(!inline_flag||!cross_module){
2721 error(33,v->identifier);
2722 }else{
2723 if(v->fi->first_ic){
2724 free_IC(v->fi->first_ic);
2725 v->fi->first_ic=0;
2726 }
2727 }
2728 }else{
2729 v->flags|=DEFINED;
2730 v->dfilename=filename;
2731 v->dline=line;
2732#ifdef HAVE_MISRA
2733/* removed */
2734/* removed */
2735/* removed */
2736/* removed */
2737/* removed */
2738#endif
2739 }
2740 if(storage_class!=EXTERN&&storage_class!=STATIC) error(34);
2741 if(extern_flag&&!inline_flag) error(120);
2742 if(storage_class==EXTERN&&!strcmp(v->identifier,"main")&&(!t->next||t->next->flags!=INT)) error(121);
2743 if(!had_decl&&v->nesting==0&&v->storage_class==EXTERN&&strcmp("main",v->identifier))
2744 error(168,v->identifier);
2745 while(!ecpp&&ctok->type!=LBRA){
2746 /* alter Stil */
2747 type *nt=declaration_specifiers();notdone=1;oldstyle=OLDSTYLE;
2748 if(!ts) {error(35);}
2749 while(notdone){
2750 int found=0;
2751 imerk=ident;ident=vident;*vident=0;
2752 ts=declarator(clone_typ(nt));
2753 ident=imerk;
2754 if(!ts) {error(36);}
2755 else{
2756 for(i=0;i<t->exact->count;i++){
2757 if(!strcmp((*t->exact->sl)[i].identifier,vident)){
2758 found=1;
2759 if((*t->exact->sl)[i].styp){
2760 error(69,vident);
2761 freetyp((*t->exact->sl)[i].styp);
2762 }
2763 /* typ[] in *typ */
2764 if(ISARRAY(ts->flags)) ts->flags=POINTER_TYPE(ts);
2765 /* typ() in *typ() */
2766 if(ISFUNC(ts->flags)){
2767 type *new=new_typ();
2768 new->flags=POINTER_TYPE(ts);
2769 new->next=ts;
2770 ts=new;
2771 }
2772 if(!return_sc) return_sc=AUTO;
2773 if(return_sc!=AUTO&&return_sc!=REGISTER)
2774 {error(122);return_sc=AUTO;}
2775 (*t->exact->sl)[i].storage_class=return_sc;
2776 (*t->exact->sl)[i].reg=return_reg;
2777 if(return_reg) error(219);
2778 (*t->exact->sl)[i].styp=ts;
2779 }
2780 }
2781 }
2782 if(!found) {error(37,vident);}
2783 killsp();
2784 if(ctok->type==COMMA) {next_token();killsp();} else notdone=0;
2785 }
2786 if(nt) freetyp(nt);
2787 if(ctok->type==SEMIC){
2788 next_token();killsp();
2789 }else{
2790 error(54);
2791 while(ctok->type!=LBRA&&ctok->type!=SEMIC){next_token();killsp();}
2792 }
2793 }
2794 if(!ecpp&&t->exact->count==0){
2795 struct_list sl[1];
2796 if(DEBUG&1) printf("prototype converted to (void)\n");
2797 t->exact->count=1;
2798 sl[0].identifier=empty;
2799 sl[0].storage_class=AUTO;
2800 sl[0].styp=new_typ();
2801 sl[0].styp->flags=VOID;
2802 sl[0].styp->next=0;
2803 sl[0].reg=0;
2804 nesting--;
2805 add_sl(t->exact,&sl);
2806 nesting++;
2807 }
2808 if(om&&om->exact&&!compare_sd(om->exact,t->exact)) {
2809 error(123);
2810#ifdef HAVE_MISRA
2811/* removed */
2812#endif
2813 }
2814 nocode=0;currentpri=1;
2815 /* enter_block();*/
2816 local_offset[1]=l2zm(0L);
2817 return_var=0;
2818 if(!v->vtyp) ierror(0);
2819#ifdef HAVE_REGPARMS
2820 reg_handle=empty_reg_handle;
2821#endif
2822 if(v->vtyp->next->flags==VOID){
2823 return_typ=0;
2824 }else{
2825 return_typ=v->vtyp->next;
2826 if(!ffreturn(return_typ)&&(return_typ->flags&NQ)!=VOID){
2827 /* Parameter fuer die Rueckgabe von Werten, die nicht in einem */
2828 /* Register sind. */
2829 type *rt=new_typ();int reg;
2830 rt->flags=POINTER_TYPE(return_typ);rt->next=return_typ;
2831#ifdef HAVE_REGPARMS
2832 reg=reg_parm(&reg_handle,rt,0,v->vtyp);
2833 if(!reg){
2834 return_var=add_var(empty,clone_typ(rt),AUTO|PARAMETER|oldstyle,0);
2835 }else{
2836 return_var=add_var(empty,clone_typ(rt),reg<0?(AUTO|PARAMETER|REGPARM|DBLPUSH|oldstyle):(AUTO|PARAMETER|REGPARM|oldstyle),0);
2837 return_var->reg=reg;
2838 }
2839#else
2840 return_var=add_var(empty,clone_typ(rt),AUTO|PARAMETER|oldstyle,0);
2841#endif
2842 return_var->flags|=DEFINED;
2843 return_var->dfilename=filename;
2844 return_var->dline=line;
2845 free(rt);
2846 }
2847 }
2848 first_ic=last_ic=0;ic_count=0;max_offset=l2zm(0L);
2849 if(!zmleq(local_offset[1],Z0)) max_offset=local_offset[1];
2850 for(i=0;i<t->exact->count;i++){
2851 /* TODO: missing pointer for struct return */
2852#ifdef HAVE_REGPARMS
2853 int didrp=0;
2854 if((*t->exact->sl)[i].styp){
2855 int tr;
2856 tr=reg_parm(&reg_handle,(*t->exact->sl)[i].styp,0,t);
2857 didrp=1;
2858 if(!(*t->exact->sl)[i].reg) (*t->exact->sl)[i].reg=tr;
2859 }
2860#endif
2861 if(!(*t->exact->sl)[i].styp&&*(*t->exact->sl)[i].identifier){
2862 type *nt;
2863#ifdef HAVE_MISRA
2864/* removed */
2865#endif
2866 nt=new_typ();
2867 nt->flags=INT;
2868 (*t->exact->sl)[i].styp=nt;
2869 (*t->exact->sl)[i].storage_class=AUTO;
2870 (*t->exact->sl)[i].reg=0;
2871 error(124);
2872 }
2873 if(*(*t->exact->sl)[i].identifier){
2874 Var *tmp;int sc,tr;
2875 sc=((*t->exact->sl)[i].storage_class|PARAMETER|oldstyle);
2876#ifdef HAVE_REGPARMS
2877 if(!didrp){
2878 if(!t->exact->sl) ierror(0);
2879 if(!(*t->exact->sl)[i].styp) ierror(0);
2880 tr=reg_parm(&reg_handle,(*t->exact->sl)[i].styp,0,t);
2881 if(!(*t->exact->sl)[i].reg) (*t->exact->sl)[i].reg=tr;
2882 }
2883#endif
2884 if((*t->exact->sl)[i].reg>0) sc|=REGPARM;
2885 if((*t->exact->sl)[i].reg<0) sc|=(REGPARM|DBLPUSH);
2886 tmp=add_var((*t->exact->sl)[i].identifier,clone_typ((*t->exact->sl)[i].styp),sc,0);
2887 tmp->reg=(*t->exact->sl)[i].reg;
2888 tmp->flags|=DEFINED;
2889 tmp->dfilename=filename;
2890 tmp->dline=line;
2891 if(oldstyle){
2892#ifdef HAVE_MISRA
2893/* removed */
2894#endif
2895 freetyp((*t->exact->sl)[i].styp);
2896 (*t->exact->sl)[i].styp=0; /* Prototype entfernen */
2897 }
2898 }
2899 }
2900 if(oldstyle) t->exact->count=0; /* Prototype entfernen */
2901 /* local_offset[1]=l2zm(0L);*/
2902 return_label=++label;
2903 function_calls=0;float_used=0;has_return=0;goto_used=0;vlas=0;
2904 did_return_label=0;
2905 for(i=1;i<=MAXR;i++) simple_scratch[i]=0;
2906 if(v->storage_class==EXTERN&&(v->flags&INLINEFUNC))
2907 disallow_statics=1;
2908#ifdef HAVE_ECPP
2909/* removed */
2910/* removed */
2911/* removed */
2912/* removed */
2913/* removed */
2914/* removed */
2915/* removed */
2916/* removed */
2917#endif
2918#ifdef HAVE_MISRA
2919/* removed */
2920/* removed */
2921#endif
2922
2923 if(c99){
2924 /* c99 predefined __func__ */
2925 type *ft=new_typ();
2926 Var *fnc;
2927
2928 /* create type */
2929 ft->flags=ARRAY;
2930 ft->size=l2zm((long)strlen(cur_func)+1);
2931 ft->next=new_typ();
2932 ft->next->flags=CONST|CHAR;
2933
2934 /* use string_expression() to create const_list */
2935 fnc=add_var("__func__",ft,STATIC,cl_from_string(cur_func,cur_func+strlen(cur_func)));
2936 fnc->flags|=DEFINED;
2937 }
2938
2939 /* Generate intermediate code for function */
2940 compound_statement();
2941
2942#ifdef HAVE_MISRA
2943/* removed */
2944#endif
2945#ifdef HAVE_ECPP
2946/* removed */
2947/* removed */
2948/* removed */
2949/* removed */
2950/* removed */
2951/* removed */
2952/* removed */
2953#endif
2954 cur_funcv=0;
2955 disallow_statics=0;
2956 if(block_vla[nesting]) clearvl();
2957 if((v->vtyp->next->flags&NQ)!=VOID&&!has_return){
2958 if(strcmp(v->identifier,"main")) error(173,v->identifier);
2959 else error(174,v->identifier);
2960 }
2961#if 0
2962 {int i;
2963 for(i=1;i<=MAXR;i++) if(regs[i]!=regsa[i]) {printf("Register %s:\n",regnames[i]);ierror(0);}
2964 }
2965#endif
2966 if(!did_return_label){
2967 clear_main_ret();
2968 gen_label(return_label);
2969 }
2970 /* backpatch code for jumps out of vla-scope if necessary */
2971 if(vlas)
2972 vla_jump_fix();
2973 if(cross_module){
2974 if(!v->fi) v->fi=new_fi();
2975 v->fi->statics=first_var[0];
2976 }else if(first_ic&&errors==0){
2977 if((c_flags[2]&USEDFLAG)&&ic1){fprintf(ic1,"function %s\n",v->identifier); pric(ic1,first_ic);}
2978 vl1=first_var[0];
2979 vl2=first_var[1];
2980 vl3=merk_varf;
2981 optimize(optflags,v);
2982 if((c_flags[3]&USEDFLAG)&&ic2){fprintf(ic2,"function %s\n",v->identifier); pric(ic2,first_ic);}
2983 if(out&&!only_inline&&!(c_flags[5]&USEDFLAG)){
2984 memset(regs_modified,0,RSIZE);
2985 gen_code(out,first_ic,v,max_offset);
2986 static_stack_check(v);
2987 v->flags|=GENERATED;
2988#ifdef HAVE_REGS_MODIFIED
2989 if(!v->fi) v->fi=new_fi();
2990 if(v->fi->flags&ALL_REGS)
2991 {
2992 int i;
2993 for(i=1;i<=MAXR;i++){
2994 if(reg_pair(i,&rp)){
2995 if(BTST(regs_modified,i)){
2996 BSET(regs_modified,rp.r1);
2997 BSET(regs_modified,rp.r2);
2998 }else{
2999 if(BTST(regs_modified,rp.r1)||BTST(regs_modified,rp.r2))
3000 BSET(regs_modified,i);
3001 }
3002 }
3003 }
3004 memcpy(v->fi->regs_modified,regs_modified,RSIZE);
3005 v->fi->flags|=ALL_REGS;
3006 }
3007#endif
3008 }
3009 /*if(DEBUG&8192){fprintf(ic2,"function %s, after gen_code\n",v->identifier); pric(ic2,first_ic);}*/
3010 free_IC(first_ic);
3011 first_ic=last_ic=0;
3012 }
3013 if(cross_module){
3014 if(!v->fi) v->fi=new_fi();
3015 v->fi->first_ic=first_ic;
3016 v->fi->last_ic=last_ic;
3017 first_ic=last_ic=0;
3018 }
3019 if(v->fi&&v->fi->first_ic){
3020 Var *vp;
3021 if(DEBUG&1) printf("leave block %d (inline-version)\n",nesting);
3022 if(block_vla[nesting]) clearvl();
3023 if(nesting!=1) ierror(0);
3024 if(merk_varl) merk_varl->next=first_var[nesting]; else merk_varf=first_var[nesting];
3025 if(last_var[nesting]) merk_varl=last_var[nesting];
3026 if(merk_sil) merk_sil->next=first_si[nesting]; else merk_sif=first_si[nesting];
3027 if(last_si[nesting]) merk_sil=last_si[nesting];
3028 if(merk_sdl) merk_sdl->next=first_sd[nesting]; else merk_sdf=first_sd[nesting];
3029 if(last_sd[nesting]) merk_sdl=last_sd[nesting];
3030 if(merk_ilistl) merk_ilistl->next=first_ilist[nesting]; else merk_ilistf=first_ilist[nesting];
3031 if(last_ilist[nesting]) merk_ilistl=last_ilist[nesting];
3032
3033 if(merk_varf&&!only_inline&&!cross_module) gen_vars(merk_varf);
3034 if(first_llist) free_llist(first_llist);
3035 first_llist=0;
3036 if(first_clist) free_clist(first_clist);
3037 first_clist=0;
3038 if(merk_sif) free_si(merk_sif);
3039 /* struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden, */
3040 /* dass struct-declarations in Prototypen frei werden und dann eine */
3041 /* spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird. */
3042 /* Nicht sehr schoen - wenn moeglich noch mal aendern. */
3043 /* if(merk_sdf) free_sd(merk_sdf);*/
3044 /* hier noch was ueberlegen */
3045 /* if(merk_ilistf) free_ilist(merk_ilistf);*/
3046 nesting--;
3047 v->fi->vars=merk_varf;
3048 /* v->fi->vars=first_var[1];*/
3049 /* keine echten Parameter=>keine negativen Offsets */
3050 /* vp=first_var[1];*/
3051 if(!cross_module){
3052 vp=merk_varf;
3053 while(vp){
3054 if(vp->storage_class==AUTO||vp->storage_class==REGISTER){
3055 /*if(DEBUG&1024) printf("handling variable %s(%ld)/%p\n",vp->identifier,zm2l(vp->offset),(void*)vp);*/
3056 if(!zmleq(l2zm(0L),vp->offset)){
3057 vp->offset=l2zm(0L);
3058 if(DEBUG&1024) printf("converted parameter <%s>(%ld) for inlining\n",vp->identifier,(long)zm2l(vp->offset));
3059 }else vp->offset=l2zm(4L); /* Dummy, da recalc_offsets? */
3060 }
3061 vp=vp->next;
3062 }
3063 }
3064 }else{
3065 leave_block();
3066 }
3067 if(only_inline==2) only_inline=0;
3068 cur_func="oops, I forgot it";
3069 }else{
3070 if(makeint) error(125);
3071 if(ctok->type==SEMIC) next_token(); else error(54);
3072 if(ISFUNC(t->flags)&&t->exact){
3073 struct_declaration *sd=t->exact;int i,f;
3074 for(f=0,i=0;i<sd->count;i++)
3075 if(!(*sd->sl)[i].styp){error(126);f=1;}
3076 if(f){
3077 for(i=0;i<sd->count;i++) if((*sd->sl)[i].styp) freetyp((*sd->sl)[i].styp);
3078 sd->count=0;
3079 }
3080 }
3081 }
3082 if(old) freetyp(old);
3083}
3084int compatible_types(type *a,type *b,int qual)
3085/* Vergleicht, ob Typ beider Typen gleich ist, const/volatile */
3086/* werden laut ANSI nicht beruecksichtigt. */
3087{
3088 struct_declaration *sd;
3089 int af=a->flags&qual,bf=b->flags&qual;
3090 if(af!=bf) return(0);
3091 af&=NQ;bf&=NQ;
3092 if(ISFUNC(af)){
3093 if(a->exact->count&&!compare_sd(a->exact,b->exact)) return(0);
3094 }
3095 if(ISSTRUCT(af)||ISUNION(af)){
3096 if(cross_module&&a->exact->tunit!=b->exact->tunit) return 1;
3097 if(a->exact!=b->exact) return(0);
3098 }
3099 if(ISARRAY(af)){
3100 if(!zmeqto(a->size,l2zm(0L))&&!zmeqto(b->size,l2zm(0L))&&!zmeqto(a->size,b->size)) return(0);
3101 }
3102 if(a->next==0&&b->next!=0) return(0);
3103 if(a->next!=0&&b->next==0) return(0);
3104 if(a->next==0&&b->next==0) return(1);
3105 if(qual!=NQ) qual=(NU|CONST|VOLATILE);
3106 return(compatible_types(a->next,b->next,qual));
3107}
3108int compare_sd(struct_declaration *a,struct_declaration *b)
3109/* Vergleicht, ob zwei struct_declarations identisch sind */
3110/* Wird nur nur fuer Prototypen benutzt, leere Liste immer gleich. */
3111{
3112 int i;
3113 if(!a->count||!b->count) return(1);
3114 if(a->count!=b->count) return(0);
3115 for(i=0;i<a->count;i++){
3116 if((*a->sl)[i].styp&&(*b->sl)[i].styp&&!compatible_types((*a->sl)[i].styp,(*b->sl)[i].styp,NU)) return(0);
3117 if((*a->sl)[i].reg!=(*b->sl)[i].reg) {error(368);return 0;}
3118#ifdef HAVE_MISRA
3119/* removed */
3120/* removed */
3121#endif
3122 }
3123 return(1);
3124}
3125void free_clist(const_list *p)
3126/* Gibt clist frei. */
3127{
3128 const_list *merk;
3129 return;
3130 while(p){
3131 merk=p->next;
3132 if(p->other) free_clist(p->other);
3133 if(p->tree) free_expression(p->tree);
3134 free(p);
3135 p=merk;
3136 }
3137}
3138void gen_clist(FILE *,type *,const_list *);
3139
3140void gen_vars(Var *v)
3141/* Generiert Variablen. */
3142{
3143 int mode,al,first_pass=1;Var *p;
3144 if(errors!=0||(c_flags[5]&USEDFLAG)) return;
3145 if(optsize)
3146 al=zm2l(maxalign);
3147 else
3148 al=0;
3149 for(;al>=0;al--){
3150 for(mode=0;mode<3;mode++){
3151 int i,flag;
3152 for(p=v;p;p=p->next){
3153 if(p->flags&NEEDS) continue;
3154 if(optsize&&zm2l(falign(p->vtyp))!=al)
3155 continue;
3156 if(cross_module&&!(p->flags&REFERENCED)) continue;
3157 if(DEBUG&2) printf("gen_var(): %s\n",p->identifier);
3158 if(p->storage_class==STATIC||p->storage_class==EXTERN){
3159 if(!(p->flags&GENERATED)){
3160 if(p->storage_class==EXTERN&&!(p->flags&(USEDASSOURCE|USEDASDEST))&&!(p->flags&(TENTATIVE|DEFINED))) continue;
3161 if(p->storage_class==STATIC&&p->nesting>0&&!(p->flags&(USEDASSOURCE|USEDASDEST))) continue;
3162 /* erst konstante initialisierte Daten */
3163 if(mode==0){
3164 if(!p->clist) continue;
3165 if(!(p->vtyp->flags&(CONST|STRINGCONST))){
3166 type *t=p->vtyp;int f=0;
3167 do{
3168 if(t->flags&(CONST|STRINGCONST)) break;
3169 if(!ISARRAY(t->flags)){f=1;break;}
3170 t=t->next;
3171 }while(1);
3172 if(f) continue;
3173 }
3174 }
3175 /* dann initiolisierte */
3176 if(mode==1&&!p->clist) continue;
3177 /* und dann der Rest */
3178
3179 if(mode==2&&p->clist) continue;
3180
3181 if(!(p->flags&(TENTATIVE|DEFINED))){
3182 if(!((p->vtyp->flags&NQ)==FUNKT)||!p->fi||!p->fi->inline_asm){
3183 if(mask_opt){
3184 if((p->flags&PRINTFLIKE)&&!strstr(p->identifier,".")) needs("vfprintf");
3185 if((p->flags&SCANFLIKE)&&!strstr(p->identifier,".")) needs("vfscanf");
3186 }
3187 gen_var_head(out,p);
3188 }
3189 if(p->storage_class==STATIC&&(!p->fi||!p->fi->inline_asm)) error(127,p->identifier);
3190 continue;
3191 }else{
3192 /*gen_align(out,falign(p->vtyp));*/
3193 }
3194 if(!((p->vtyp->flags&NQ)==FUNKT)||!p->fi||!p->fi->inline_asm){
3195 if(mask_opt){
3196 if((p->flags&PRINTFLIKE)&&!strstr(p->identifier,".")) needs("vfprintf");
3197 if((p->flags&SCANFLIKE)&&!strstr(p->identifier,".")) needs("vfscanf");
3198 }
3199 gen_var_head(out,p);
3200 }
3201 if(!p->clist){
3202 if(type_uncomplete(p->vtyp)) error(202,p->identifier);
3203 gen_ds(out,szof(p->vtyp),p->vtyp);
3204 }else{
3205 gen_clist(out,p->vtyp,p->clist);
3206 }
3207 p->flags|=GENERATED;
3208 }else if(p->flags&INLINEEXT){
3209 /* a function was declared extern inline and defined;
3210 we have to create external linkage */
3211 int m=p->flags;
3212 /* pretend, it was only declared, but not defined and remove
3213 INLINEEXT */
3214 p->flags&=~(DEFINED|INLINEEXT);
3215 gen_var_head(out,p);
3216 p->flags|=DEFINED;
3217 }
3218 }
3219 }
3220 first_pass=0;
3221 }
3222 }
3223 if(mask_opt){
3224 for(p=v;p;p=p->next)
3225 if(p->flags&NEEDS) gen_var_head(out,p);
3226 }
3227}
3228
3229/* creates code that dynamically initializes a variable */
3230void dynamic_init(Var *v,type *t,const_list *cl,zmax of,int noconst)
3231{
3232 int f=t->flags;
3233 if(ISARRAY(f)){
3234 zmax i;
3235 for(i=l2zm(0L);!zmleq(t->size,i);i=zmadd(i,l2zm(1L))){
3236 if(cl&&zmeqto(cl->idx,i)){
3237 dynamic_init(v,t->next,cl->other,of,noconst);
3238 cl=cl->next;
3239 }else{
3240 dynamic_init(v,t->next,0,of,noconst);
3241 }
3242 of=zmadd(of,szof(t->next));
3243 }
3244 }else if(ISUNION(f)&&(!cl||!cl->tree)){
3245 dynamic_init(v,(*t->exact->sl)[cl?zm2l(cl->idx):0].styp,cl?cl->other:0,of,noconst);
3246 }else if(ISSTRUCT(f)&&(!cl||!cl->tree)){
3247 zmax al;int fl;type *st;
3248 int bfo,i;
3249 for(i=0;i<t->exact->count&&cl;i++){
3250 if(!cl->other){
3251 if(errors==0)
3252 ierror(0);
3253 return;
3254 }
3255 st=(*t->exact->sl)[i].styp;
3256 al=(*t->exact->sl)[i].align;
3257 if(!(*t->exact->sl)[i].identifier) ierror(0);
3258 bfo=(*t->exact->sl)[i].bfoffset;
3259 if(!zmeqto(zmmod(of,al),l2zm(0L))){
3260 of=zmadd(of,zmsub(al,zmmod(of,al)));
3261 }
3262 if(bfo>=0){
3263 int bfs=(*t->exact->sl)[i].bfsize;
3264 static obj dest = {0};
3265
3266 dest.flags=VAR;
3267 dest.v=v;
3268 dest.val.vmax=of;
3269
3270 if(bfo==0){
3271 /* first clear entire bitfield */
3272 IC *new=new_IC();
3273 new->code=ASSIGN;
3274 new->z=dest;
3275 new->typf=st->flags;
3276 new->q2.val.vmax=sizetab[st->flags&NQ];
3277 new->q1.flags=KONST;
3278 new->q1.val.vmax=l2zm(0L);
3279 eval_const(&new->q1.val,MAXINT);
3280 insert_const(&new->q1.val,st->flags&NU);
3281 add_IC(new);
3282 }
3283
3284 /* bitfield */
3285 if(!zmeqto(cl->idx,l2zm(i))||!cl->other){
3286 /* nothing to do, initialized before */
3287 }else if(cl->other->tree){
3288 obj dummy;
3289 gen_IC(cl->other->tree,0,0);
3290 convert(cl->other->tree,st->flags);
3291 insert_bitfield(&dest,&cl->other->tree->o,&cl->other->tree->o,bfs,bfo,st->flags,1);
3292 cl=cl->next;
3293 }else{
3294 static obj val = {0};
3295 val.flags=KONST;
3296 val.val=cl->other->val;
3297 insert_bitfield(&dest,&val,&val,bfs,bfo,st->flags,1);
3298 cl=cl->next;
3299 }
3300 if(i+1>=t->exact->count||(*t->exact->sl)[i+1].bfoffset<=0||!cl){
3301 of=zmadd(of,szof(st));
3302 }
3303 }else{
3304 if(zmeqto(l2zm((long)i),cl->idx)){
3305 dynamic_init(v,st,cl->other,of,noconst);
3306 cl=cl->next;
3307 }else
3308 dynamic_init(v,st,0,of,noconst);
3309 of=zmadd(of,szof(st));
3310 }
3311 }
3312 for(;i<t->exact->count;i++){
3313 st=(*t->exact->sl)[i].styp;
3314 al=(*t->exact->sl)[i].align;
3315 bfo=(*t->exact->sl)[i].bfoffset;
3316 if(bfo>0) continue;
3317 if(!zmeqto(zmmod(of,al),l2zm(0L))){
3318 of=zmadd(of,zmsub(al,zmmod(of,al)));
3319 }
3320 dynamic_init(v,st,0,of,noconst);
3321 of=zmadd(of,szof(st));
3322 }
3323 }else{
3324 IC *new;
3325 if(noconst&&(!cl||!cl->tree))
3326 return;
3327 new=new_IC();
3328 new->code=ASSIGN;
3329 new->z.flags=VAR;
3330 new->z.v=v;
3331 new->z.val.vmax=of;
3332 new->typf=t->flags;
3333 new->q2.val.vmax=szof(t);
3334 if(!cl){
3335 new->q1.flags=KONST;
3336 gval.vmax=l2zm(0L);
3337 eval_const(&gval,MAXINT);
3338 insert_const(&new->q1.val,t->flags&NU);
3339 }else if(cl->tree){
3340 gen_IC(cl->tree,0,0);
3341 if(ISSCALAR(t->flags))
3342 convert(cl->tree,t->flags);
3343 new->q1=cl->tree->o;
3344 }else{
3345 new->q1.flags=KONST;
3346 new->q1.val=cl->val;
3347 }
3348 add_IC(new);
3349 }
3350}
3351
3352
3353void gen_clist(FILE *f,type *t,const_list *cl)
3354/* Generiert dc fuer const_list. */
3355{
3356 int i,bfo,bfs;zmax sz;zumax bfval=ul2zum(0UL);
3357
3358#if 0
3359 for(i=0;i<(int)szof(t);i++){
3360 zuchar c;int s;
3361 s=get_clist_byte(t,cl,i,&c);
3362 printf("%03d: 0x%02x (%d)\n",i,(int)c,s);
3363 }
3364#endif
3365
3366
3367 if(ISARRAY(t->flags)){
3368 for(sz=l2zm(0L);!zmleq(t->size,sz)&&cl;cl=cl->next){
3369 if(!cl->other){ierror(0);return;}
3370 if(!zmeqto(sz,cl->idx))
3371 gen_ds(f,zmmult(zmsub(cl->idx,sz),szof(t->next)),t->next);
3372
3373 gen_clist(f,t->next,cl->other);
3374 sz=zmadd(cl->idx,l2zm(1L));
3375 }
3376 if(!zmleq(t->size,sz)) gen_ds(f,zmmult(zmsub(t->size,sz),szof(t->next)),t->next);
3377 return;
3378 }
3379 if(ISUNION(t->flags)){
3380 int i=zm2l(cl->idx);
3381 if(cl&&cl->tree){
3382 /* union initialized by another union */
3383 gen_ds(f,szof(t),t);
3384 }else{
3385 gen_clist(f,(*t->exact->sl)[i].styp,cl->other);
3386 sz=zmsub(szof(t),szof((*t->exact->sl)[i].styp));
3387 if(!zmeqto(sz,l2zm(0L))) gen_ds(f,sz,0);
3388 }
3389 return;
3390 }
3391 if(ISSTRUCT(t->flags)){
3392 zmax al;int fl;type *st;
3393 sz=l2zm(0L);
3394 if(cl&&cl->tree){
3395 /* initialized by another */
3396 gen_ds(f,szof(t),t);
3397 sz=zmadd(sz,szof(t));
3398 }else{
3399 for(i=0;i<t->exact->count&&cl;i++){
3400 if(!cl->other){ierror(0);return;}
3401 st=(*t->exact->sl)[i].styp;
3402 al=(*t->exact->sl)[i].align;
3403 if(!(*t->exact->sl)[i].identifier) ierror(0);
3404 bfo=(*t->exact->sl)[i].bfoffset;
3405 if(!zmeqto(zmmod(sz,al),l2zm(0L))){
3406 gen_ds(f,zmsub(al,zmmod(sz,al)),0);
3407 sz=zmadd(sz,zmsub(al,zmmod(sz,al)));
3408 }
3409 if(bfo>=0){
3410 /* bitfield */
3411 if((*t->exact->sl)[i].identifier[0]){
3412 bfs=(*t->exact->sl)[i].bfsize;
3413 if(zmeqto(l2zm((long)i),cl->idx)){
3414 eval_const(&cl->other->val,st->flags);
3415 cl=cl->next;
3416 }else{
3417 vumax=ul2zum(0UL);
3418 }
3419 vumax=zumand(vumax,zumsub(zumlshift(ul2zum(1UL),ul2zum((unsigned long)bfs)),ul2zum(1UL)));
3420 bfval=zumor(bfval,zumlshift(vumax,ul2zum((unsigned long)bflayout(bfo,bfs,st->flags))));
3421 }
3422 if(i+1>=t->exact->count||(*t->exact->sl)[i+1].bfoffset<=0||!cl){
3423 /* last bitfield in integer */
3424 const_list bfcl;
3425 gval.vumax=bfval;
3426 eval_const(&gval,UNSIGNED|MAXINT);
3427 insert_const(&bfcl.val,st->flags&NU);
3428 bfcl.tree=0;
3429 gen_dc(f,st->flags&NU,&bfcl);
3430 bfval=ul2zum(0L);
3431 sz=zmadd(sz,szof(st));
3432 }
3433 }else{
3434 if(zmeqto(l2zm((long)i),cl->idx)){
3435 gen_clist(f,st,cl->other);
3436 cl=cl->next;
3437 }else
3438 gen_ds(f,szof(st),st);
3439 sz=zmadd(sz,szof(st));
3440 }
3441 }
3442 for(;i<t->exact->count;i++){
3443 st=(*t->exact->sl)[i].styp;
3444 al=(*t->exact->sl)[i].align;
3445 bfo=(*t->exact->sl)[i].bfoffset;
3446 if(bfo>0) continue;
3447 if(!zmeqto(zmmod(sz,al),l2zm(0L))){
3448 gen_ds(f,zmsub(al,zmmod(sz,al)),0);
3449 sz=zmadd(sz,zmsub(al,zmmod(sz,al)));
3450 }
3451 gen_ds(f,szof((*t->exact->sl)[i].styp),(*t->exact->sl)[i].styp);
3452 sz=zmadd(sz,szof(st));
3453 }
3454 }
3455 al=falign(t);
3456 if(!zmeqto(zmmod(sz,al),l2zm(0L)))
3457 gen_ds(f,zmsub(al,zmmod(sz,al)),0);
3458 return;
3459 }
3460
3461 if(cl->tree) cl->tree->o.am=0;
3462
3463 if(zmeqto(cl->idx,l2zm(-1L)))
3464 gen_ds(f,szof(t),t);
3465 else
3466 gen_dc(f,t->flags&NU,cl);
3467}
3468
3469/* finds the correct place in a const list to insert new initializer */
3470const_list *insert_cl(const_list *old,zmax idx)
3471{
3472 const_list *p,*cl=0;
3473 if(old&&zmleq(old->idx,idx)){
3474 p=old;
3475 do{
3476 if(zmeqto(p->idx,idx)){
3477 /* found existing entry */
3478 cl=p;
3479 break;
3480 }
3481 if(!p->next||!zmleq(p->next->idx,idx))
3482 break;
3483 p=p->next;
3484 }while(p);
3485 }else
3486 p=0;
3487 /* we need a new entry */
3488 if(!cl){
3489 cl=mymalloc(CLS);
3490 cl->tree=0;
3491 cl->other=0;
3492 cl->idx=idx;
3493 if(p){
3494 cl->next=p->next;
3495 p->next=cl;
3496 }else
3497 cl->next=old;
3498 }
3499 return cl;
3500}
3501
3502const_list *designator(type *t,const_list *cl)
3503{
3504 int f=t->flags&NQ;
3505 np tree;
3506 if(!c99) return 0;
3507 if(ISARRAY(f)&&ctok->type==LBRK){
3508 next_token();
3509 killsp();
3510 tree=expression();
3511 if(ctok->type!=RBRK)
3512 error(62);
3513 else
3514 {next_token();killsp();}
3515 if(!type_expression(tree,0)){
3516 /* error("incorrect constant expression");*/
3517 }else{
3518 if(tree->sidefx) error(60);
3519 if(tree->flags!=CEXPR||!ISINT(tree->ntyp->flags)){
3520 error(19);
3521 }else{
3522 /* check index for valid range */
3523 eval_constn(tree);
3524 if(!zmleq(l2zm(0L),vmax)) {error(354);vmax=l2zm(0L);}
3525 if(!zmeqto(t->size,l2zm(0L))&&zmleq(t->size,vmax)) {error(354);vmax=l2zm(0L);}
3526
3527 cl=insert_cl(cl,vmax);
3528
3529 return cl;
3530 }
3531 }
3532 }else if((ISSTRUCT(f)||ISUNION(f))&&ctok->type==DOT){
3533 next_token();
3534 killsp();
3535 if(ctok->type!=NAME){
3536 error(53);
3537 }else{
3538 int i,n=-1;
3539 for(i=0;i<t->exact->count;i++)
3540 if(!strcmp((*t->exact->sl)[i].identifier,ctok->name)) n=i;
3541 if(n<0){
3542 error(23,ctok->name);
3543 return 0;
3544 }
3545 next_token();
3546 killsp();
3547
3548 if(!ISUNION(f)||!cl)
3549 cl=insert_cl(cl,l2zm((long)n));
3550
3551 return cl;
3552 }
3553 }
3554 return 0;
3555}
3556
3557/* declare a builtin function with up to two scalar arguments */
3558Var *declare_builtin(char *name,int ztyp,int q1typ,int q1reg,int q2typ,int q2reg,int nosidefx,char *asm)
3559{
3560 struct_declaration *sd;
3561 type *t;
3562 Var *v;
3563 int args;
3564 if(!(v=find_ext_var(name))){
3565 sd=mymalloc(sizeof(*sd));
3566 if(q1typ==0) args=1;
3567 else if(q2typ!=0) args=3;
3568 else args=2;
3569 sd->sl=mymalloc(args*sizeof(struct_list));
3570 memset(sd->sl,0,args*sizeof(struct_list));
3571 sd->count=args;
3572 if(q1typ){
3573 (*sd->sl)[0].styp=new_typ();
3574 (*sd->sl)[0].styp->flags=q1typ;
3575 (*sd->sl)[0].reg=q1reg;
3576 }
3577 if(q2typ){
3578 (*sd->sl)[1].styp=new_typ();
3579 (*sd->sl)[1].styp->flags=q2typ;
3580 (*sd->sl)[1].reg=q2reg;
3581 }
3582 (*sd->sl)[args-1].styp=new_typ();
3583 (*sd->sl)[args-1].styp->flags=VOID;
3584 (*sd->sl)[args-1].reg=0;
3585 t=new_typ();
3586 t->flags=FUNKT;
3587 t->exact=add_sd(sd,FUNKT);
3588 t->next=new_typ();
3589 t->next->flags=ztyp;
3590 v=add_var(name,t,EXTERN,0);
3591 v->flags|=BUILTIN;
3592 if(asm||nosidefx){
3593 v->fi=new_fi();
3594 if(asm) v->fi->inline_asm=asm;
3595 if(nosidefx){
3596 v->fi->call_cnt=v->fi->use_cnt=v->fi->change_cnt=0;
3597 v->fi->flags=ALL_CALLS|ALL_USES|ALL_MODS|ALWAYS_RETURNS|NOSIDEFX;
3598 }
3599 }
3600 }
3601 return v;
3602}
3603
3604
3605const_list *initialization(type *t,int noconst,int level,int desi,struct_declaration *fstruct,const_list *first)
3606/* Traegt eine Initialisierung in eine const_list ein. */
3607{
3608 const_list *cl,**prev;
3609 np tree,tree2;
3610 int bracket,desi_follows=0;
3611 zmax i;
3612 token mtok;
3613
3614 int f=t->flags&NQ;
3615 if(ISFUNC(f)){error(42);return(0);}
3616 if(ctok->type==LBRA){next_token();killsp();bracket=1;} else bracket=0;
3617 if(ISARRAY(f)){
3618#ifdef HAVE_MISRA
3619/* removed */
3620#endif
3621 if(t->dsize){
3622 error(358);
3623 }else if(zmeqto(t->size,l2zm(0L))&&level!=0){
3624 error(359);
3625 }else if(ctok->type==T_STRING&&t->next&&(t->next->flags&NQ)==CHAR){
3626 killsp();
3627 tree=string_expression();
3628 first=tree->cl;
3629 free_expression(tree);
3630 }else{
3631 const_list *last=first;
3632 if(level==0&&!bracket) error(157);
3633 for(i=l2zm(0L);desi_follows||((zmeqto(t->size,l2zm(0L))||!zmleq(t->size,i)||ctok->type==LBRK)&&ctok->type!=RBRA);i=zmadd(i,l2zm(1L))){
3634 if(!zmleq(i,0)){
3635 if(ctok->type==COMMA){next_token();killsp();} else break;
3636 if(ctok->type==RBRA) break;
3637 }
3638 /* check for first designated initializer */
3639 cl=designator(t,first);
3640 if(!cl){
3641 /* no designator */
3642 cl=insert_cl(last,i);
3643 cl->other=initialization(t->next,c99?noconst:0,level+1,0,fstruct,cl->other);
3644 if(cl->other&&zmeqto(cl->other->idx,l2zm(-2L))){
3645 first=cl->other;
3646 first->other=0;
3647 break;
3648 }
3649 }else{
3650 /* designator: store current object and handle remaining designators */
3651 i=cl->idx;
3652 if(ctok->type!=ASGN){
3653 if(ctok->type!=LBRK&&ctok->type!=DOT)
3654 error(355);
3655 }else{
3656 cl->other=0;
3657 next_token();killsp();
3658 }
3659 cl->other=initialization(t->next,c99?noconst:0,level+1,1,fstruct,cl->other);
3660 }
3661 if(cl->next==first) first=cl;
3662 last=cl;
3663 killsp();
3664 if(desi&&!bracket)
3665 break;
3666 desi_follows=0;
3667 if(ctok->type==COMMA){
3668 copy_token(&mtok,ctok);
3669 next_token();killsp();
3670 if(ctok->type==LBRK)
3671 desi_follows=1;
3672 push_token(&mtok);
3673 }
3674 }
3675
3676 if(bracket&&zmeqto(i,l2zm(0L))) error(360);
3677
3678#ifdef HAVE_MISRA
3679/* removed */
3680/* removed */
3681/* removed */
3682/* removed */
3683#endif
3684 }
3685 }else if(ISSTRUCT(f)&&(bracket||!noconst||c99)){
3686 if(t->exact->count<=0)
3687 {error(43);return(0);}
3688#ifdef HAVE_ECPP
3689/* removed */
3690#endif
3691 prev=0;
3692 if(level==0&&!bracket&&!c99) error(157);
3693 for(i=l2zm(0L);desi_follows||(!zmleq(t->exact->count,i)&&ctok->type!=RBRA);i=zmadd(i,l2zm(1L))){
3694 if(!desi_follows&&(*t->exact->sl)[zm2l(i)].identifier[0]==0) continue; /* unnamed bitfield */
3695 if(!zmleq(i,0)){
3696 if(ctok->type==COMMA){next_token();killsp();} else break;
3697 if(ctok->type==RBRA) break;
3698 }
3699 cl=designator(t,first);
3700
3701 if(!cl){
3702 cl=insert_cl(first,l2zm((long)i));
3703 cl->other=initialization((*t->exact->sl)[zm2l(i)].styp,c99?noconst:0,level+1,0,!fstruct&&!bracket&&zmeqto(i,l2zm(0L))?t->exact:fstruct,cl->other);
3704 if(cl->other&&zmeqto(cl->other->idx,l2zm(-2L))){
3705 if(fstruct){
3706 first=cl->other;
3707 first->other=0;
3708 }else{
3709 *cl=*cl->other;
3710 cl->idx=l2zm(-1L);
3711 cl->other=0;
3712 first=cl;
3713 }
3714 break;
3715 }
3716 }else{
3717 i=zm2l(cl->idx);
3718 if(ctok->type!=ASGN){
3719 if(ctok->type!=LBRK&&ctok->type!=DOT)
3720 error(355);
3721 }else{
3722 next_token();killsp();
3723 cl->other=0;
3724 }
3725 cl->other=initialization((*t->exact->sl)[zm2l(i)].styp,c99?noconst:0,level+1,1,fstruct,cl->other);
3726 }
3727 if(cl->next==first) first=cl;
3728 if(desi&&!bracket)
3729 break;
3730 desi_follows=0;
3731 if(ctok->type==COMMA){
3732 copy_token(&mtok,ctok);
3733 next_token();killsp();
3734 if(ctok->type==DOT)
3735 desi_follows=1;
3736 push_token(&mtok);
3737 }
3738 }
3739
3740 if(bracket&&zmeqto(i,l2zm(0L))) error(360);
3741
3742#ifdef HAVE_MISRA
3743/* removed */
3744/* removed */
3745/* removed */
3746/* removed */
3747#endif
3748
3749 }else if(ISUNION(f)&&(c99||bracket||!noconst)){
3750 if(t->exact->count<=0)
3751 {error(44);return(0);}
3752
3753 if(level==0&&!bracket&&!c99) error(157);
3754 desi_follows=1;
3755 while(desi_follows){
3756 cl=designator(t,first);
3757
3758 if(!cl){
3759 cl=insert_cl(first,l2zm((long)0));
3760 cl->other=initialization((*t->exact->sl)[0].styp,c99?noconst:0,level+1,0,!fstruct&&!bracket?t->exact:fstruct,cl->other);
3761 if(cl->other&&zmeqto(cl->other->idx,l2zm(-2L))){
3762 if(fstruct){
3763 first=cl->other;
3764 first->other=0;
3765 }else{
3766 *cl=*cl->other;
3767 cl->other=0;
3768 cl->idx=l2zm(-1L);
3769 first=cl;
3770 }
3771 break;
3772 }
3773 }else{
3774 i=zm2l(cl->idx);
3775 if(ctok->type!=ASGN){
3776 if(ctok->type!=LBRK&&ctok->type!=DOT)
3777 error(355);
3778 }else{
3779 next_token();killsp();
3780 cl->other=0;
3781 }
3782 cl->other=initialization((*t->exact->sl)[zm2l(i)].styp,c99?noconst:0,level+1,1,fstruct,cl->other);
3783 }
3784 first=cl;
3785 if(desi&&!bracket)
3786 break;
3787 desi_follows=0;
3788 if(ctok->type==COMMA){
3789 copy_token(&mtok,ctok);
3790 next_token();killsp();
3791 if(ctok->type==DOT)
3792 desi_follows=1;
3793 else
3794 push_token(&mtok);
3795 }
3796 }
3797 }else{
3798 int oldconst=const_expr;
3799 tree2=tree=assignment_expression();
3800
3801 if(!tree){error(45);return(0);}
3802 if(!noconst) const_expr=1;
3803 if(!type_expression(tree,t)){free_expression(tree); const_expr=oldconst;return 0;}
3804 const_expr=oldconst;
3805
3806 tree=makepointer(tree);
3807
3808 /* check for complete assignment in dynamic initialization */
3809 if(noconst&&(ISSTRUCT(tree->ntyp->flags)||ISUNION(tree->ntyp->flags))&&fstruct==tree->ntyp->exact){
3810 first=mymalloc(CLS);
3811 first->tree=tree;
3812 first->next=first->other=0;
3813 first->idx=l2zm(-2L);
3814 return first;
3815 }
3816
3817 if(!test_assignment(t,tree)){free_expression(tree); return 0;}
3818 if(!noconst){
3819 /* nur Konstanten erlaubt (bei Arrays/Strukturen etc. oder static) */
3820 if(tree->flags!=CEXPR){
3821 /*while(tree->flags==CAST) tree=tree->left;*/
3822 if(!tree->sidefx/*tree->flags==ADDRESS||tree->flags==ADDRESSS||tree->flags==ADDRESSA*/){
3823 const_expr=1;
3824 gen_IC(tree,0,0);
3825 const_expr=oldconst;
3826 if(!(tree->o.flags&VARADR)){
3827 /* hier fehlen noch viele Pruefungen */
3828 free_expression(tree);error(46);
3829 return(0);
3830 }
3831 tree->o.v->flags|=USEDASADR;
3832 first=mymalloc(CLS);
3833 first->next=first->other=0;
3834 first->tree=tree;
3835 first->idx=l2zm(0L);
3836 killsp();
3837 }else{
3838 free_expression(tree);error(46);
3839 return(0);
3840 }
3841 }else{
3842 first=mymalloc(CLS);
3843 first->idx=l2zm(0L);
3844 first->next=first->other=0;
3845 first->tree=0;
3846 eval_constn(tree);
3847 tree->ntyp->flags=t->flags;
3848 insert_constn(tree);
3849 first->val=tree->val;
3850 free_expression(tree2);
3851 killsp();
3852 }
3853 }else{
3854 /* auch anderes erlaubt */
3855 first=mymalloc(CLS);
3856 first->next=first->other=0;
3857 first->tree=tree;
3858 killsp();
3859 if(!tree->sidefx){
3860 if(tree->flags==CEXPR){
3861 eval_constn(tree);
3862 tree->ntyp->flags=t->flags;
3863 insert_constn(tree);
3864 first->val=tree->val;
3865 first->tree=0;
3866 first->idx=l2zm(0L);
3867 init_const_sz=zmadd(init_const_sz,szof(tree->ntyp));
3868 init_const_cnt++;
3869 free_expression(tree2);
3870 }else{
3871 first->idx=l2zm(-1L);
3872 init_dyn_sz=zmadd(init_dyn_sz,szof(tree->ntyp));
3873 init_dyn_cnt++;
3874 }
3875 }else{
3876 first->idx=l2zm(-1L);
3877 init_dyn_sz=zmadd(init_dyn_sz,szof(tree->ntyp));
3878 init_dyn_cnt++;
3879 }
3880 }
3881 }
3882 if(bracket){
3883 if(ctok->type==COMMA){next_token();killsp();}
3884 if(ctok->type==RBRA){next_token();killsp();} else error(128);
3885 }
3886 return(first);
3887}
3888#ifdef HAVE_ECPP
3889/* removed */
3890/* removed */
3891/* removed */
3892/* removed */
3893/* removed */
3894/* removed */
3895/* removed */
3896/* removed */
3897/* removed */
3898/* removed */
3899/* removed */
3900/* removed */
3901/* removed */
3902/* removed */
3903/* removed */
3904/* removed */
3905/* removed */
3906/* removed */
3907/* removed */
3908/* removed */
3909/* removed */
3910/* removed */
3911/* removed */
3912/* removed */
3913/* removed */
3914/* removed */
3915/* removed */
3916/* removed */
3917/* removed */
3918/* removed */
3919/* removed */
3920/* removed */
3921/* removed */
3922/* removed */
3923/* removed */
3924/* removed */
3925/* removed */
3926/* removed */
3927/* removed */
3928/* removed */
3929/* removed */
3930/* removed */
3931/* removed */
3932/* removed */
3933/* removed */
3934/* removed */
3935/* removed */
3936/* removed */
3937/* removed */
3938/* removed */
3939/* removed */
3940/* removed */
3941/* removed */
3942/* removed */
3943/* removed */
3944/* removed */
3945/* removed */
3946/* removed */
3947/* removed */
3948/* removed */
3949/* removed */
3950/* removed */
3951/* removed */
3952/* removed */
3953/* removed */
3954/* removed */
3955/* removed */
3956/* removed */
3957/* removed */
3958/* removed */
3959/* removed */
3960/* removed */
3961/* removed */
3962/* removed */
3963/* removed */
3964/* removed */
3965/* removed */
3966/* removed */
3967/* removed */
3968/* removed */
3969/* removed */
3970/* removed */
3971/* removed */
3972/* removed */
3973/* removed */
3974/* removed */
3975/* removed */
3976/* removed */
3977/* removed */
3978/* removed */
3979/* removed */
3980/* removed */
3981/* removed */
3982/* removed */
3983/* removed */
3984/* removed */
3985/* removed */
3986/* removed */
3987/* removed */
3988/* removed */
3989/* removed */
3990/* removed */
3991/* removed */
3992/* removed */
3993/* removed */
3994/* removed */
3995/* removed */
3996/* removed */
3997/* removed */
3998/* removed */
3999/* removed */
4000/* removed */
4001/* removed */
4002/* removed */
4003/* removed */
4004/* removed */
4005/* removed */
4006/* removed */
4007/* removed */
4008/* removed */
4009/* removed */
4010/* removed */
4011/* removed */
4012/* removed */
4013/* removed */
4014/* removed */
4015/* removed */
4016/* removed */
4017/* removed */
4018/* removed */
4019/* removed */
4020/* removed */
4021/* removed */
4022/* removed */
4023/* removed */
4024/* removed */
4025/* removed */
4026/* removed */
4027/* removed */
4028/* removed */
4029/* removed */
4030/* removed */
4031/* removed */
4032/* removed */
4033/* removed */
4034/* removed */
4035/* removed */
4036/* removed */
4037/* removed */
4038/* removed */
4039/* removed */
4040/* removed */
4041/* removed */
4042/* removed */
4043/* removed */
4044/* removed */
4045/* removed */
4046/* removed */
4047/* removed */
4048/* removed */
4049/* removed */
4050/* removed */
4051/* removed */
4052/* removed */
4053/* removed */
4054/* removed */
4055/* removed */
4056/* removed */
4057/* removed */
4058/* removed */
4059/* removed */
4060/* removed */
4061/* removed */
4062/* removed */
4063/* removed */
4064/* removed */
4065/* removed */
4066/* removed */
4067/* removed */
4068/* removed */
4069/* removed */
4070/* removed */
4071/* removed */
4072/* removed */
4073/* removed */
4074/* removed */
4075/* removed */
4076/* removed */
4077/* removed */
4078/* removed */
4079/* removed */
4080/* removed */
4081/* removed */
4082/* removed */
4083/* removed */
4084/* removed */
4085/* removed */
4086/* removed */
4087/* removed */
4088/* removed */
4089/* removed */
4090/* removed */
4091/* removed */
4092/* removed */
4093/* removed */
4094/* removed */
4095/* removed */
4096/* removed */
4097/* removed */
4098/* removed */
4099/* removed */
4100/* removed */
4101/* removed */
4102/* removed */
4103/* removed */
4104/* removed */
4105/* removed */
4106/* removed */
4107/* removed */
4108/* removed */
4109/* removed */
4110/* removed */
4111/* removed */
4112/* removed */
4113/* removed */
4114/* removed */
4115/* removed */
4116/* removed */
4117/* removed */
4118/* removed */
4119/* removed */
4120/* removed */
4121/* removed */
4122/* removed */
4123/* removed */
4124/* removed */
4125/* removed */
4126/* removed */
4127/* removed */
4128/* removed */
4129/* removed */
4130/* removed */
4131/* removed */
4132/* removed */
4133/* removed */
4134/* removed */
4135/* removed */
4136/* removed */
4137/* removed */
4138/* removed */
4139/* removed */
4140/* removed */
4141/* removed */
4142/* removed */
4143/* removed */
4144/* removed */
4145/* removed */
4146/* removed */
4147/* removed */
4148/* removed */
4149/* removed */
4150/* removed */
4151/* removed */
4152/* removed */
4153/* removed */
4154/* removed */
4155/* removed */
4156/* removed */
4157/* removed */
4158/* removed */
4159/* removed */
4160/* removed */
4161/* removed */
4162/* removed */
4163/* removed */
4164/* removed */
4165/* removed */
4166/* removed */
4167/* removed */
4168/* removed */
4169/* removed */
4170/* removed */
4171/* removed */
4172/* removed */
4173/* removed */
4174/* removed */
4175/* removed */
4176/* removed */
4177/* removed */
4178/* removed */
4179/* removed */
4180/* removed */
4181/* removed */
4182/* removed */
4183/* removed */
4184/* removed */
4185/* removed */
4186/* removed */
4187/* removed */
4188/* removed */
4189/* removed */
4190/* removed */
4191/* removed */
4192/* removed */
4193/* removed */
4194/* removed */
4195/* removed */
4196/* removed */
4197/* removed */
4198/* removed */
4199/* removed */
4200/* removed */
4201/* removed */
4202/* removed */
4203/* removed */
4204/* removed */
4205/* removed */
4206/* removed */
4207/* removed */
4208/* removed */
4209/* removed */
4210/* removed */
4211/* removed */
4212/* removed */
4213/* removed */
4214/* removed */
4215/* removed */
4216/* removed */
4217/* removed */
4218/* removed */
4219/* removed */
4220/* removed */
4221/* removed */
4222/* removed */
4223/* removed */
4224/* removed */
4225/* removed */
4226/* removed */
4227/* removed */
4228/* removed */
4229/* removed */
4230/* removed */
4231/* removed */
4232/* removed */
4233/* removed */
4234/* removed */
4235/* removed */
4236/* removed */
4237/* removed */
4238/* removed */
4239/* removed */
4240/* removed */
4241/* removed */
4242/* removed */
4243/* removed */
4244/* removed */
4245/* removed */
4246/* removed */
4247/* removed */
4248/* removed */
4249/* removed */
4250/* removed */
4251/* removed */
4252/* removed */
4253/* removed */
4254/* removed */
4255/* removed */
4256/* removed */
4257/* removed */
4258/* removed */
4259/* removed */
4260/* removed */
4261/* removed */
4262/* removed */
4263/* removed */
4264/* removed */
4265/* removed */
4266/* removed */
4267/* removed */
4268/* removed */
4269/* removed */
4270/* removed */
4271/* removed */
4272/* removed */
4273/* removed */
4274/* removed */
4275/* removed */
4276/* removed */
4277/* removed */
4278/* removed */
4279/* removed */
4280/* removed */
4281/* removed */
4282/* removed */
4283/* removed */
4284/* removed */
4285/* removed */
4286/* removed */
4287/* removed */
4288/* removed */
4289/* removed */
4290/* removed */
4291/* removed */
4292/* removed */
4293/* removed */
4294/* removed */
4295/* removed */
4296/* removed */
4297/* removed */
4298/* removed */
4299/* removed */
4300/* removed */
4301/* removed */
4302/* removed */
4303/* removed */
4304/* removed */
4305/* removed */
4306/* removed */
4307/* removed */
4308/* removed */
4309/* removed */
4310/* removed */
4311/* removed */
4312/* removed */
4313/* removed */
4314/* removed */
4315/* removed */
4316/* removed */
4317/* removed */
4318/* removed */
4319/* removed */
4320/* removed */
4321/* removed */
4322/* removed */
4323/* removed */
4324/* removed */
4325/* removed */
4326/* removed */
4327/* removed */
4328/* removed */
4329/* removed */
4330/* removed */
4331/* removed */
4332/* removed */
4333/* removed */
4334/* removed */
4335/* removed */
4336/* removed */
4337/* removed */
4338/* removed */
4339/* removed */
4340/* removed */
4341/* removed */
4342/* removed */
4343/* removed */
4344/* removed */
4345/* removed */
4346/* removed */
4347/* removed */
4348/* removed */
4349/* removed */
4350/* removed */
4351/* removed */
4352/* removed */
4353/* removed */
4354/* removed */
4355/* removed */
4356/* removed */
4357/* removed */
4358/* removed */
4359/* removed */
4360/* removed */
4361/* removed */
4362/* removed */
4363/* removed */
4364/* removed */
4365/* removed */
4366/* removed */
4367/* removed */
4368/* removed */
4369/* removed */
4370/* removed */
4371/* removed */
4372/* removed */
4373/* removed */
4374/* removed */
4375/* removed */
4376/* removed */
4377/* removed */
4378/* removed */
4379/* removed */
4380/* removed */
4381/* removed */
4382/* removed */
4383/* removed */
4384/* removed */
4385/* removed */
4386/* removed */
4387/* removed */
4388/* removed */
4389/* removed */
4390/* removed */
4391/* removed */
4392/* removed */
4393/* removed */
4394/* removed */
4395/* removed */
4396/* removed */
4397/* removed */
4398/* removed */
4399/* removed */
4400/* removed */
4401/* removed */
4402/* removed */
4403/* removed */
4404/* removed */
4405/* removed */
4406/* removed */
4407/* removed */
4408/* removed */
4409/* removed */
4410/* removed */
4411/* removed */
4412/* removed */
4413/* removed */
4414/* removed */
4415/* removed */
4416/* removed */
4417/* removed */
4418/* removed */
4419/* removed */
4420/* removed */
4421/* removed */
4422/* removed */
4423/* removed */
4424/* removed */
4425/* removed */
4426/* removed */
4427/* removed */
4428/* removed */
4429/* removed */
4430/* removed */
4431/* removed */
4432/* removed */
4433/* removed */
4434/* removed */
4435/* removed */
4436/* removed */
4437/* removed */
4438/* removed */
4439/* removed */
4440/* removed */
4441/* removed */
4442/* removed */
4443/* removed */
4444/* removed */
4445/* removed */
4446/* removed */
4447/* removed */
4448/* removed */
4449/* removed */
4450/* removed */
4451/* removed */
4452/* removed */
4453/* removed */
4454/* removed */
4455/* removed */
4456/* removed */
4457/* removed */
4458/* removed */
4459/* removed */
4460/* removed */
4461/* removed */
4462/* removed */
4463/* removed */
4464/* removed */
4465/* removed */
4466/* removed */
4467/* removed */
4468/* removed */
4469/* removed */
4470/* removed */
4471/* removed */
4472/* removed */
4473/* removed */
4474/* removed */
4475/* removed */
4476/* removed */
4477/* removed */
4478/* removed */
4479/* removed */
4480/* removed */
4481/* removed */
4482/* removed */
4483/* removed */
4484/* removed */
4485/* removed */
4486/* removed */
4487/* removed */
4488/* removed */
4489/* removed */
4490/* removed */
4491/* removed */
4492/* removed */
4493/* removed */
4494/* removed */
4495/* removed */
4496/* removed */
4497/* removed */
4498/* removed */
4499/* removed */
4500/* removed */
4501/* removed */
4502/* removed */
4503/* removed */
4504/* removed */
4505/* removed */
4506/* removed */
4507/* removed */
4508/* removed */
4509/* removed */
4510/* removed */
4511/* removed */
4512/* removed */
4513/* removed */
4514/* removed */
4515/* removed */
4516/* removed */
4517/* removed */
4518/* removed */
4519/* removed */
4520/* removed */
4521/* removed */
4522/* removed */
4523/* removed */
4524/* removed */
4525/* removed */
4526/* removed */
4527/* removed */
4528/* removed */
4529/* removed */
4530/* removed */
4531/* removed */
4532/* removed */
4533/* removed */
4534/* removed */
4535/* removed */
4536/* removed */
4537/* removed */
4538/* removed */
4539/* removed */
4540/* removed */
4541/* removed */
4542/* removed */
4543/* removed */
4544/* removed */
4545/* removed */
4546/* removed */
4547/* removed */
4548/* removed */
4549/* removed */
4550/* removed */
4551/* removed */
4552/* removed */
4553/* removed */
4554/* removed */
4555/* removed */
4556/* removed */
4557/* removed */
4558/* removed */
4559/* removed */
4560/* removed */
4561/* removed */
4562/* removed */
4563/* removed */
4564/* removed */
4565/* removed */
4566/* removed */
4567/* removed */
4568/* removed */
4569/* removed */
4570/* removed */
4571/* removed */
4572/* removed */
4573/* removed */
4574/* removed */
4575/* removed */
4576/* removed */
4577/* removed */
4578/* removed */
4579/* removed */
4580/* removed */
4581/* removed */
4582/* removed */
4583/* removed */
4584/* removed */
4585/* removed */
4586/* removed */
4587/* removed */
4588/* removed */
4589/* removed */
4590/* removed */
4591/* removed */
4592/* removed */
4593/* removed */
4594/* removed */
4595/* removed */
4596/* removed */
4597/* removed */
4598/* removed */
4599/* removed */
4600/* removed */
4601/* removed */
4602/* removed */
4603/* removed */
4604/* removed */
4605/* removed */
4606/* removed */
4607/* removed */
4608/* removed */
4609/* removed */
4610/* removed */
4611/* removed */
4612/* removed */
4613/* removed */
4614/* removed */
4615/* removed */
4616/* removed */
4617/* removed */
4618/* removed */
4619/* removed */
4620/* removed */
4621/* removed */
4622/* removed */
4623/* removed */
4624/* removed */
4625/* removed */
4626/* removed */
4627/* removed */
4628/* removed */
4629/* removed */
4630/* removed */
4631/* removed */
4632/* removed */
4633/* removed */
4634/* removed */
4635/* removed */
4636/* removed */
4637/* removed */
4638/* removed */
4639/* removed */
4640/* removed */
4641/* removed */
4642/* removed */
4643/* removed */
4644/* removed */
4645/* removed */
4646/* removed */
4647/* removed */
4648/* removed */
4649/* removed */
4650/* removed */
4651/* removed */
4652/* removed */
4653/* removed */
4654/* removed */
4655/* removed */
4656/* removed */
4657/* removed */
4658/* removed */
4659/* removed */
4660/* removed */
4661/* removed */
4662/* removed */
4663/* removed */
4664/* removed */
4665/* removed */
4666/* removed */
4667/* removed */
4668/* removed */
4669/* removed */
4670/* removed */
4671/* removed */
4672/* removed */
4673/* removed */
4674/* removed */
4675/* removed */
4676/* removed */
4677/* removed */
4678/* removed */
4679/* removed */
4680/* removed */
4681/* removed */
4682/* removed */
4683/* removed */
4684/* removed */
4685/* removed */
4686/* removed */
4687/* removed */
4688/* removed */
4689/* removed */
4690/* removed */
4691/* removed */
4692/* removed */
4693/* removed */
4694/* removed */
4695/* removed */
4696/* removed */
4697/* removed */
4698/* removed */
4699/* removed */
4700/* removed */
4701/* removed */
4702/* removed */
4703/* removed */
4704/* removed */
4705/* removed */
4706/* removed */
4707/* removed */
4708/* removed */
4709/* removed */
4710/* removed */
4711/* removed */
4712/* removed */
4713/* removed */
4714/* removed */
4715/* removed */
4716/* removed */
4717/* removed */
4718/* removed */
4719/* removed */
4720/* removed */
4721/* removed */
4722/* removed */
4723/* removed */
4724/* removed */
4725/* removed */
4726/* removed */
4727/* removed */
4728/* removed */
4729/* removed */
4730/* removed */
4731/* removed */
4732/* removed */
4733/* removed */
4734/* removed */
4735/* removed */
4736/* removed */
4737/* removed */
4738/* removed */
4739/* removed */
4740/* removed */
4741/* removed */
4742/* removed */
4743/* removed */
4744/* removed */
4745/* removed */
4746/* removed */
4747/* removed */
4748/* removed */
4749/* removed */
4750/* removed */
4751/* removed */
4752/* removed */
4753/* removed */
4754/* removed */
4755/* removed */
4756/* removed */
4757/* removed */
4758/* removed */
4759/* removed */
4760/* removed */
4761/* removed */
4762/* removed */
4763/* removed */
4764/* removed */
4765/* removed */
4766/* removed */
4767/* removed */
4768/* removed */
4769/* removed */
4770/* removed */
4771/* removed */
4772/* removed */
4773/* removed */
4774/* removed */
4775/* removed */
4776/* removed */
4777/* removed */
4778/* removed */
4779/* removed */
4780/* removed */
4781#endif