/* $VER: vbcc (main.c) V0.8 */#include "vbcc_cpp.h"#include "vbc.h"#include "opt.h"static char FILE_[]=__FILE__;void do_function(struct Var *);static struct function_info *current_fi;struct token *ctok;struct lexer_state ls;int endok=1;int line,errors;bvtype task_preempt_regs[RSIZE/sizeof(bvtype)];bvtype task_schedule_regs[RSIZE/sizeof(bvtype)];char *multname[]={"","s"};void raus(void)/* Beendet das Programm */{ static int inraus; if(inraus) return; inraus = 1; if(DEBUG) printf("raus()\n"); if(!endok) fprintf(stderr,"unexpected end of file\n"); if(errors) fprintf(stderr,"%d error%s found!\n",errors,multname[errors>1]); if(debug_info&&out) cleanup_db(out); while(nesting>=0) leave_block(); /*FIXME: do I have to close input-file? */ if(!wpo) cleanup_cg(out); emit_flush(out); if(cmdfile) fclose(cmdfile); if(out) fclose(out); if(ic1) fclose(ic1); if(ic2) fclose(ic2); /*FIXME: need to cleanup something for ucpp?*/; if(endok&&!errors) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE);}int eof;void translation_unit(void)/* bearbeitet translation_unit *//* hier z.Z. nur provisorisch */{ struct Var *p; if(cross_module){ for(p=first_ext;p;p=p->next) if(!(p->flags&BUILTIN)) p->flags|=NOTINTU; } while(1){ killsp(); if(eof||ctok->type!=NAME){ if(!eof){ error(0); raus(); }else{ if(cross_module){ int n=0; if(last_tunit){ last_tunit->next=mymalloc(sizeof(*first_tunit)); last_tunit=last_tunit->next; }else{ first_tunit=last_tunit=mymalloc(sizeof(*first_tunit)); } last_tunit->next=0; for(p=first_var[0];p;p=p->next){ if(p->storage_class==STATIC) n++; } last_tunit->statics=first_var[0]; return; }else{ raus(); } } } endok=0; var_declaration(); endok=1; }}void reserve_reg(char *p) /* reserviert ein Register */{ int i; if(*p!='=') error(4,"-reserve-reg"); for(i=1;i<=MAXR;i++){ if(!strcmp(p+1,regnames[i])) break; } if(i>MAXR){ error(331,p+1); }else{ regsa[i]=1; }} void dontwarn(char *p)/* schaltet flags fuer Meldung auf DONTWARN */{ if(*p!='=') error(4,"-dontwarn"); do{ int i=atoi(p+1); if(i>=err_num) error(159,i); if(i<0){ for(i=0;i<err_num;i++) if(!(err_out[i].flags&(ANSIV|FATAL))) err_out[i].flags|=DONTWARN; return; } if(err_out[i].flags&(ANSIV|FATAL)) error(160,i); err_out[i].flags|=DONTWARN; p=strchr(p+1,','); } while(p);} #define MISRA_98_RULE_NUMBER 127#define MISRA_04_CHAPTER 21#define MISRA_04_MAX_RULE_IN_CHAPTER 17 static int misra_98_warn_flag[MISRA_98_RULE_NUMBER] = { 0 };static int misra_04_warn_flag[MISRA_04_CHAPTER][MISRA_04_MAX_RULE_IN_CHAPTER] = { 0 }; void misrawarn(char *p) { int rule,subrule,misraoldrule; char* last; int not_found; struct misra_err_out* misr_err; rule = 0; subrule = 0; misraoldrule = 0; if(*p!='=') error(4,"-misrawarn"); p++; if (!(strncmp("chapter",p,6))) { if (sscanf((p+7),"%d",&rule) != 1) { error(327,"-misrawarn"); } } else if ( !(strncmp("misra98rule",p,11))) { if (sscanf((p+12),"%d",&misraoldrule) != 1) { error(327,"-misrawarn"); } } else { if (last = strchr(p,'.')) { *last = 0; last++; if (sscanf(last,"%d",&subrule) != 1) error(327,"-misrawarn"); if (sscanf(p,"%d",&rule) != 1) error(327,"-misrawarn"); last--; *last='.'; } else error(327,"-misrawarn"); } p--; if (!misracheck) misracheck = 1; if (misraoldrule) { if (misraversion==2004) error(328,misraversion,"-misrawarn",p); if (!misraversion) misraversion=1998; if ((misraoldrule < 1) || (misraoldrule>MISRA_98_RULE_NUMBER)) error(329,misraoldrule,"-misrawarn",p); misra_98_warn_flag[misraoldrule-1] = 1; } else { if (misraversion==1998) error(328,misraversion,"-misrawarn",p); if (!misraversion) misraversion=2004; if (subrule) { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if ((misr_err->chapter == rule) && (misr_err->rule == subrule)) { not_found = 0; break; } misr_err++; } if (not_found) error(330,rule,subrule,"-misrawarn",p); misra_04_warn_flag[rule-1][subrule-1] = 1; } else { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if (misr_err->chapter == rule) { not_found = 0; misra_04_warn_flag[misr_err->chapter-1][misr_err->rule-1] = 1; } misr_err++; } if (not_found) error(330,rule,subrule,"-misrawarn",p); } } } void misradontwarn(char *p) { int rule,subrule,misraoldrule; char* last; int not_found; struct misra_err_out* misr_err; rule = 0; subrule = 0; misraoldrule = 0; if(*p!='=') error(4,"-misradontwarn"); p++; if (!(strncmp("chapter",p,6))) { if (sscanf((p+7),"%d",&rule) != 1) { error(327,"-misradontwarn"); } } else if ( !(strncmp("misra98rule",p,11))) { if (sscanf((p+12),"%d",&misraoldrule) != 1) { error(327,"-misradontwarn"); } } else { if (last = strchr(p,'.')) { *last = 0; last++; if (sscanf(last,"%d",&subrule) != 1) error(327,"-misradontwarn"); if (sscanf(p,"%d",&rule) != 1) error(327,"-misradontwarn"); last--; *last='.'; } else error(327,"-misradontwarn"); } p--; if (misraoldrule) { if (misraversion==2004) error(328,misraversion,"-misradontwarn",p); if ((misraoldrule < 1) || (misraoldrule>MISRA_98_RULE_NUMBER)) error(329,misraoldrule,"-misradontwarn",p); misra_98_warn_flag[misraoldrule-1] = -1; } else { if (misraversion==1998) error(328,misraversion,"-misradontwarn",p); if (subrule) { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if ((misr_err->chapter == rule) && (misr_err->rule == subrule)) { not_found = 0; break; } misr_err++; } if (not_found) error(330,rule,subrule,"-misradontwarn",p); misra_04_warn_flag[rule-1][subrule-1] = -1; } else { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if (misr_err->chapter == rule) { not_found = 0; misra_04_warn_flag[misr_err->chapter-1][misr_err->rule-1] = -1; } misr_err++; } if (not_found) error(330,rule,subrule,"-misradontwarn",p); } } } void warn(char *p)/* schaltet Warnung fuer Meldung ein *//* wenn Nummer<0 sind alle Warnungen ein */{ int i; if(*p!='=') error(4,"-warn"); i=atoi(p+1); if(i>=err_num) error(159,i); if(i<0){ for(i=0;i<err_num;i++) err_out[i].flags&=~DONTWARN; return; }else err_out[i].flags&=~DONTWARN;}void gen_function(FILE *f,struct Var *v,int real_gen){ struct IC *p,*new;int i,had_regs; if(DEBUG&1) printf("gen_function <%s>,f=%p,real_gen=%d\n",v->identifier,(void*)f,real_gen); if(!v->fi) ierror(0); if(errors!=0) return; first_ic=last_ic=0; for(i=1;i<=MAXR;i++) {regs[i]=regused[i]=regsa[i];regsbuf[i]=0;} function_calls=0;vlas=0; if(!real_gen){ for(p=v->fi->first_ic;p;p=p->next){ new=new_IC(); *new=*p; p->copy=new; add_IC(new); new->file=p->file; new->line=p->line; if(p->code==CALL){ int i; function_calls++; if((p->q1.flags&VAR)&&!strcmp(p->q1.v->identifier,"__allocvla")){ vlas=1; v->fi->flags|=USES_VLA; } new->arg_list=mymalloc(sizeof(*new->arg_list)*new->arg_cnt); for(i=0;i<new->arg_cnt;i++) new->arg_list[i]=p->arg_list[i]->copy; } } }else{ for(i=1;i<=MAXR;i++) regused[i]=0; for(p=v->fi->opt_ic;p;p=p->next){ if(p->code==ALLOCREG){ regused[p->q1.reg]=1; if(reg_pair(p->q1.reg,&rp)){ regused[rp.r1]=1; regused[rp.r2]=1; } } if(p->code==CALL){ if((p->q1.flags&VAR)&&!strcmp(p->q1.v->identifier,"__allocvla")) vlas=1; function_calls++; } } } if(vlas&&FPVLA_REG) regs[FPVLA_REG]=regused[FPVLA_REG]=regsa[FPVLA_REG]=regscratch[FPVLA_REG]=1; if(!real_gen&&(c_flags[2]&USEDFLAG)&&ic1){ fprintf(ic1,"function %s\n",v->identifier); pric(ic1,first_ic); } vl0=first_ext; vl1=v->fi->statics; vl2=0; vl3=v->fi->vars; nesting=1; first_var[nesting]=last_var[nesting]=0; cur_func=v->identifier; if(!real_gen){ optimize(optflags,v); memset(regs_modified,0,RSIZE); /* pseudeo generator pass to get regs_modified */ v->fi->opt_ic=clone_ic(first_ic); v->fi->max_offset=max_offset; if(v->fi&&(v->fi->flags&ALL_REGS)) had_regs=1; else had_regs=0; gen_code(0,first_ic,v,max_offset);#ifdef HAVE_REGS_MODIFIED if(!v->fi) v->fi=new_fi(); { int i;struct IC *p; for(i=1;i<=MAXR;i++){ if(BTST(regs_modified,i)&®_pair(i,&rp)){ BSET(regs_modified,rp.r1); BSET(regs_modified,rp.r2); } }#if 1 for(i=1;i<=MAXR;i++){ if(reg_pair(i,&rp)){ if(BTST(regs_modified,rp.r1)||BTST(regs_modified,rp.r2)) BSET(regs_modified,i); } }#endif if(had_regs){ if(memcmp(regs_modified,v->fi->regs_modified,RSIZE)) error(321,v->identifier); }else memcpy(v->fi->regs_modified,regs_modified,RSIZE);#if 0 printf("regs for %s (ALL_REGS=%d):\n",v->identifier,v->fi->flags&ALL_REGS); for(i=1;i<MAXR;i++) if(BTST(regs_modified,i)) printf("%s ",regnames[i]); printf("\n");#endif }#endif v->flags|=GENERATED; free_IC(first_ic); first_ic=last_ic=0; /*free_var(first_var[nesting]);*/ nesting=0; }else{ if((c_flags[3]&USEDFLAG)&&ic2){ fprintf(ic2,"function %s\n",v->identifier); pric(ic2,v->fi->opt_ic); } gen_code(f,v->fi->opt_ic,v,v->fi->max_offset); static_stack_check(v); }}/* handle functions in a const list before caller */static void do_clist_calls(struct const_list *cl){ while(cl){ if(cl->tree&&(cl->tree->o.flags&VARADR)){ struct Var *v=cl->tree->o.v; if(ISFUNC(v->vtyp->flags)){ printf(":: %s\n",v->identifier); do_function(v); } } if(cl->other) do_clist_calls(cl->other); cl=cl->next; }}void do_function(struct Var *v){ int i;struct IC *p; if((v->flags&(GENERATED|DEFINED))!=DEFINED) return; v->flags|=GENERATED; if(!v->fi) v->fi=new_fi();#if 0 for(i=0;i<v->fi->call_cnt;i++){ if(v->fi->call_list[i].v->flags&DEFINED) do_function(v->fi->call_list[i].v); }#endif /* handle callees before caller */ for(p=v->fi->first_ic;p;p=p->next){ /* direct call */ if(p->code==CALL&&(p->q1.flags&(VAR|DREFOBJ))==VAR) do_function(p->q1.v); /* function address is also a candidate */ if((p->q1.flags&(VAR|VARADR))&&ISFUNC(p->q1.v->vtyp->flags)) do_function(p->q1.v); if((p->q2.flags&(VAR|VARADR))&&ISFUNC(p->q2.v->vtyp->flags)) do_function(p->q2.v); if((p->z.flags&(VAR|VARADR))&&ISFUNC(p->z.v->vtyp->flags)) do_function(p->z.v); /* indirect call, handle special case */ if(p->code==CALL&&(p->q1.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){ struct Var *v=p->q1.v; if(v->storage_class==AUTO||v->storage_class==REGISTER){ struct IC *m=p->prev;struct Var *tmp=0; while(m&&(m->code<LABEL||m->code>=BRA)){ if(!tmp&&(m->z.flags&(VAR|DREFOBJ))==VAR&&m->z.v==v&& (m->q1.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)) tmp=m->q1.v; if(tmp&&(m->z.flags&(VAR|DREFOBJ))==VAR&&m->z.v==tmp&& (m->q1.flags&(VAR|VARADR))==(VAR|VARADR)&& m->q1.v->clist&&is_const(m->q1.v->vtyp)){ do_clist_calls(m->q1.v->clist); } m=m->prev; } } } } gen_function(0,v,0);} extern char *copyright;int main(int argc,char *argv[]){ int i,j,*fname=malloc(argc*sizeof(int)),files=0; unsigned long ucpp_flags=LEXER|WARN_TRIGRAPHS|WARN_STANDARD|WARN_ANNOYING/*|CCHARSET*/|HANDLE_PRAGMA|COPY_LINE|WARN_TRIGRAPHS_MORE|HANDLE_TRIGRAPHS; if(!fname) ierror(0); memset(fname,0,argc*sizeof(int)); c_flags_val[9].f=dontwarn; c_flags_val[10].f=warn; c_flags_val[42].f=misrawarn; c_flags_val[43].f=misradontwarn; c_flags_val[44].f=reserve_reg; for(i=1;i<argc;i++){ if(*argv[i]!='-'){ /* kein Flag */ fname[i]=1; files++; if(!inname) inname=argv[i]; }else{ int flag=0; if(argv[i][1]=='D'||argv[i][1]=='I') flag=1; for(j=0;j<MAXCF&&flag==0;j++){ size_t l; if(!c_flags_name[j]) continue; l=strlen(c_flags_name[j]); if(l>0&&!strncmp(argv[i]+1,c_flags_name[j],l)&&(argv[i][1+l]==0||argv[i][1+l]=='=')){ flag=1; if((c_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;} c_flags[j]|=USEDFLAG; if(c_flags[j]&STRINGFLAG){ if(argv[i][l+1]!='='){error(3,argv[i]);} if(argv[i][l+2]||i>=argc-1) c_flags_val[j].p=&argv[i][l+2]; else c_flags_val[j].p=&argv[++i][0]; } if(c_flags[j]&VALFLAG){ if(argv[i][l+1]!='='){error(4,argv[i]);} if(argv[i][l+2]||i>=argc-1) c_flags_val[j].l=atol(&argv[i][l+2]); else c_flags_val[j].l=atol(&argv[++i][0]); } if(c_flags[j]&FUNCFLAG) c_flags_val[j].f(&argv[i][l+1]); } } for(j=0;j<MAXGF&&flag==0;j++){ size_t l; if(!g_flags_name[j]) continue; l=strlen(g_flags_name[j]); if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){ flag=1; if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;} g_flags[j]|=USEDFLAG; if(g_flags[j]&STRINGFLAG){Lines 1–500 of 1906. Load more
/* $VER: vbcc (main.c) V0.8 */ #include "vbcc_cpp.h" #include "vbc.h" #include "opt.h" static char FILE_[]=__FILE__; void do_function(struct Var *); static struct function_info *current_fi; struct token *ctok; struct lexer_state ls; int endok=1; int line,errors; bvtype task_preempt_regs[RSIZE/sizeof(bvtype)]; bvtype task_schedule_regs[RSIZE/sizeof(bvtype)]; char *multname[]={"","s"}; void raus(void) /* Beendet das Programm */ { static int inraus; if(inraus) return; inraus = 1; if(DEBUG) printf("raus()\n"); if(!endok) fprintf(stderr,"unexpected end of file\n"); if(errors) fprintf(stderr,"%d error%s found!\n",errors,multname[errors>1]); if(debug_info&&out) cleanup_db(out); while(nesting>=0) leave_block(); /*FIXME: do I have to close input-file? */ if(!wpo) cleanup_cg(out); emit_flush(out); if(cmdfile) fclose(cmdfile); if(out) fclose(out); if(ic1) fclose(ic1); if(ic2) fclose(ic2); /*FIXME: need to cleanup something for ucpp?*/; if(endok&&!errors) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE); } int eof; void translation_unit(void) /* bearbeitet translation_unit */ /* hier z.Z. nur provisorisch */ { struct Var *p; if(cross_module){ for(p=first_ext;p;p=p->next) if(!(p->flags&BUILTIN)) p->flags|=NOTINTU; } while(1){ killsp(); if(eof||ctok->type!=NAME){ if(!eof){ error(0); raus(); }else{ if(cross_module){ int n=0; if(last_tunit){ last_tunit->next=mymalloc(sizeof(*first_tunit)); last_tunit=last_tunit->next; }else{ first_tunit=last_tunit=mymalloc(sizeof(*first_tunit)); } last_tunit->next=0; for(p=first_var[0];p;p=p->next){ if(p->storage_class==STATIC) n++; } last_tunit->statics=first_var[0]; return; }else{ raus(); } } } endok=0; var_declaration(); endok=1; } } void reserve_reg(char *p) /* reserviert ein Register */ { int i; if(*p!='=') error(4,"-reserve-reg"); for(i=1;i<=MAXR;i++){ if(!strcmp(p+1,regnames[i])) break; } if(i>MAXR){ error(331,p+1); }else{ regsa[i]=1; } } void dontwarn(char *p) /* schaltet flags fuer Meldung auf DONTWARN */ { if(*p!='=') error(4,"-dontwarn"); do{ int i=atoi(p+1); if(i>=err_num) error(159,i); if(i<0){ for(i=0;i<err_num;i++) if(!(err_out[i].flags&(ANSIV|FATAL))) err_out[i].flags|=DONTWARN; return; } if(err_out[i].flags&(ANSIV|FATAL)) error(160,i); err_out[i].flags|=DONTWARN; p=strchr(p+1,','); } while(p); } #define MISRA_98_RULE_NUMBER 127 #define MISRA_04_CHAPTER 21 #define MISRA_04_MAX_RULE_IN_CHAPTER 17 static int misra_98_warn_flag[MISRA_98_RULE_NUMBER] = { 0 }; static int misra_04_warn_flag[MISRA_04_CHAPTER][MISRA_04_MAX_RULE_IN_CHAPTER] = { 0 }; void misrawarn(char *p) { int rule,subrule,misraoldrule; char* last; int not_found; struct misra_err_out* misr_err; rule = 0; subrule = 0; misraoldrule = 0; if(*p!='=') error(4,"-misrawarn"); p++; if (!(strncmp("chapter",p,6))) { if (sscanf((p+7),"%d",&rule) != 1) { error(327,"-misrawarn"); } } else if ( !(strncmp("misra98rule",p,11))) { if (sscanf((p+12),"%d",&misraoldrule) != 1) { error(327,"-misrawarn"); } } else { if (last = strchr(p,'.')) { *last = 0; last++; if (sscanf(last,"%d",&subrule) != 1) error(327,"-misrawarn"); if (sscanf(p,"%d",&rule) != 1) error(327,"-misrawarn"); last--; *last='.'; } else error(327,"-misrawarn"); } p--; if (!misracheck) misracheck = 1; if (misraoldrule) { if (misraversion==2004) error(328,misraversion,"-misrawarn",p); if (!misraversion) misraversion=1998; if ((misraoldrule < 1) || (misraoldrule>MISRA_98_RULE_NUMBER)) error(329,misraoldrule,"-misrawarn",p); misra_98_warn_flag[misraoldrule-1] = 1; } else { if (misraversion==1998) error(328,misraversion,"-misrawarn",p); if (!misraversion) misraversion=2004; if (subrule) { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if ((misr_err->chapter == rule) && (misr_err->rule == subrule)) { not_found = 0; break; } misr_err++; } if (not_found) error(330,rule,subrule,"-misrawarn",p); misra_04_warn_flag[rule-1][subrule-1] = 1; } else { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if (misr_err->chapter == rule) { not_found = 0; misra_04_warn_flag[misr_err->chapter-1][misr_err->rule-1] = 1; } misr_err++; } if (not_found) error(330,rule,subrule,"-misrawarn",p); } } } void misradontwarn(char *p) { int rule,subrule,misraoldrule; char* last; int not_found; struct misra_err_out* misr_err; rule = 0; subrule = 0; misraoldrule = 0; if(*p!='=') error(4,"-misradontwarn"); p++; if (!(strncmp("chapter",p,6))) { if (sscanf((p+7),"%d",&rule) != 1) { error(327,"-misradontwarn"); } } else if ( !(strncmp("misra98rule",p,11))) { if (sscanf((p+12),"%d",&misraoldrule) != 1) { error(327,"-misradontwarn"); } } else { if (last = strchr(p,'.')) { *last = 0; last++; if (sscanf(last,"%d",&subrule) != 1) error(327,"-misradontwarn"); if (sscanf(p,"%d",&rule) != 1) error(327,"-misradontwarn"); last--; *last='.'; } else error(327,"-misradontwarn"); } p--; if (misraoldrule) { if (misraversion==2004) error(328,misraversion,"-misradontwarn",p); if ((misraoldrule < 1) || (misraoldrule>MISRA_98_RULE_NUMBER)) error(329,misraoldrule,"-misradontwarn",p); misra_98_warn_flag[misraoldrule-1] = -1; } else { if (misraversion==1998) error(328,misraversion,"-misradontwarn",p); if (subrule) { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if ((misr_err->chapter == rule) && (misr_err->rule == subrule)) { not_found = 0; break; } misr_err++; } if (not_found) error(330,rule,subrule,"-misradontwarn",p); misra_04_warn_flag[rule-1][subrule-1] = -1; } else { misr_err = misra_err_out; not_found = 1; while ( misr_err->text ) { if (misr_err->chapter == rule) { not_found = 0; misra_04_warn_flag[misr_err->chapter-1][misr_err->rule-1] = -1; } misr_err++; } if (not_found) error(330,rule,subrule,"-misradontwarn",p); } } } void warn(char *p) /* schaltet Warnung fuer Meldung ein */ /* wenn Nummer<0 sind alle Warnungen ein */ { int i; if(*p!='=') error(4,"-warn"); i=atoi(p+1); if(i>=err_num) error(159,i); if(i<0){ for(i=0;i<err_num;i++) err_out[i].flags&=~DONTWARN; return; }else err_out[i].flags&=~DONTWARN; } void gen_function(FILE *f,struct Var *v,int real_gen) { struct IC *p,*new;int i,had_regs; if(DEBUG&1) printf("gen_function <%s>,f=%p,real_gen=%d\n",v->identifier,(void*)f,real_gen); if(!v->fi) ierror(0); if(errors!=0) return; first_ic=last_ic=0; for(i=1;i<=MAXR;i++) {regs[i]=regused[i]=regsa[i];regsbuf[i]=0;} function_calls=0;vlas=0; if(!real_gen){ for(p=v->fi->first_ic;p;p=p->next){ new=new_IC(); *new=*p; p->copy=new; add_IC(new); new->file=p->file; new->line=p->line; if(p->code==CALL){ int i; function_calls++; if((p->q1.flags&VAR)&&!strcmp(p->q1.v->identifier,"__allocvla")){ vlas=1; v->fi->flags|=USES_VLA; } new->arg_list=mymalloc(sizeof(*new->arg_list)*new->arg_cnt); for(i=0;i<new->arg_cnt;i++) new->arg_list[i]=p->arg_list[i]->copy; } } }else{ for(i=1;i<=MAXR;i++) regused[i]=0; for(p=v->fi->opt_ic;p;p=p->next){ if(p->code==ALLOCREG){ regused[p->q1.reg]=1; if(reg_pair(p->q1.reg,&rp)){ regused[rp.r1]=1; regused[rp.r2]=1; } } if(p->code==CALL){ if((p->q1.flags&VAR)&&!strcmp(p->q1.v->identifier,"__allocvla")) vlas=1; function_calls++; } } } if(vlas&&FPVLA_REG) regs[FPVLA_REG]=regused[FPVLA_REG]=regsa[FPVLA_REG]=regscratch[FPVLA_REG]=1; if(!real_gen&&(c_flags[2]&USEDFLAG)&&ic1){ fprintf(ic1,"function %s\n",v->identifier); pric(ic1,first_ic); } vl0=first_ext; vl1=v->fi->statics; vl2=0; vl3=v->fi->vars; nesting=1; first_var[nesting]=last_var[nesting]=0; cur_func=v->identifier; if(!real_gen){ optimize(optflags,v); memset(regs_modified,0,RSIZE); /* pseudeo generator pass to get regs_modified */ v->fi->opt_ic=clone_ic(first_ic); v->fi->max_offset=max_offset; if(v->fi&&(v->fi->flags&ALL_REGS)) had_regs=1; else had_regs=0; gen_code(0,first_ic,v,max_offset); #ifdef HAVE_REGS_MODIFIED if(!v->fi) v->fi=new_fi(); { int i;struct IC *p; for(i=1;i<=MAXR;i++){ if(BTST(regs_modified,i)&®_pair(i,&rp)){ BSET(regs_modified,rp.r1); BSET(regs_modified,rp.r2); } } #if 1 for(i=1;i<=MAXR;i++){ if(reg_pair(i,&rp)){ if(BTST(regs_modified,rp.r1)||BTST(regs_modified,rp.r2)) BSET(regs_modified,i); } } #endif if(had_regs){ if(memcmp(regs_modified,v->fi->regs_modified,RSIZE)) error(321,v->identifier); }else memcpy(v->fi->regs_modified,regs_modified,RSIZE); #if 0 printf("regs for %s (ALL_REGS=%d):\n",v->identifier,v->fi->flags&ALL_REGS); for(i=1;i<MAXR;i++) if(BTST(regs_modified,i)) printf("%s ",regnames[i]); printf("\n"); #endif } #endif v->flags|=GENERATED; free_IC(first_ic); first_ic=last_ic=0; /*free_var(first_var[nesting]);*/ nesting=0; }else{ if((c_flags[3]&USEDFLAG)&&ic2){ fprintf(ic2,"function %s\n",v->identifier); pric(ic2,v->fi->opt_ic); } gen_code(f,v->fi->opt_ic,v,v->fi->max_offset); static_stack_check(v); } } /* handle functions in a const list before caller */ static void do_clist_calls(struct const_list *cl) { while(cl){ if(cl->tree&&(cl->tree->o.flags&VARADR)){ struct Var *v=cl->tree->o.v; if(ISFUNC(v->vtyp->flags)){ printf(":: %s\n",v->identifier); do_function(v); } } if(cl->other) do_clist_calls(cl->other); cl=cl->next; } } void do_function(struct Var *v) { int i;struct IC *p; if((v->flags&(GENERATED|DEFINED))!=DEFINED) return; v->flags|=GENERATED; if(!v->fi) v->fi=new_fi(); #if 0 for(i=0;i<v->fi->call_cnt;i++){ if(v->fi->call_list[i].v->flags&DEFINED) do_function(v->fi->call_list[i].v); } #endif /* handle callees before caller */ for(p=v->fi->first_ic;p;p=p->next){ /* direct call */ if(p->code==CALL&&(p->q1.flags&(VAR|DREFOBJ))==VAR) do_function(p->q1.v); /* function address is also a candidate */ if((p->q1.flags&(VAR|VARADR))&&ISFUNC(p->q1.v->vtyp->flags)) do_function(p->q1.v); if((p->q2.flags&(VAR|VARADR))&&ISFUNC(p->q2.v->vtyp->flags)) do_function(p->q2.v); if((p->z.flags&(VAR|VARADR))&&ISFUNC(p->z.v->vtyp->flags)) do_function(p->z.v); /* indirect call, handle special case */ if(p->code==CALL&&(p->q1.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){ struct Var *v=p->q1.v; if(v->storage_class==AUTO||v->storage_class==REGISTER){ struct IC *m=p->prev;struct Var *tmp=0; while(m&&(m->code<LABEL||m->code>=BRA)){ if(!tmp&&(m->z.flags&(VAR|DREFOBJ))==VAR&&m->z.v==v&& (m->q1.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)) tmp=m->q1.v; if(tmp&&(m->z.flags&(VAR|DREFOBJ))==VAR&&m->z.v==tmp&& (m->q1.flags&(VAR|VARADR))==(VAR|VARADR)&& m->q1.v->clist&&is_const(m->q1.v->vtyp)){ do_clist_calls(m->q1.v->clist); } m=m->prev; } } } } gen_function(0,v,0); } extern char *copyright; int main(int argc,char *argv[]) { int i,j,*fname=malloc(argc*sizeof(int)),files=0; unsigned long ucpp_flags=LEXER|WARN_TRIGRAPHS|WARN_STANDARD|WARN_ANNOYING/*|CCHARSET*/|HANDLE_PRAGMA|COPY_LINE|WARN_TRIGRAPHS_MORE|HANDLE_TRIGRAPHS; if(!fname) ierror(0); memset(fname,0,argc*sizeof(int)); c_flags_val[9].f=dontwarn; c_flags_val[10].f=warn; c_flags_val[42].f=misrawarn; c_flags_val[43].f=misradontwarn; c_flags_val[44].f=reserve_reg; for(i=1;i<argc;i++){ if(*argv[i]!='-'){ /* kein Flag */ fname[i]=1; files++; if(!inname) inname=argv[i]; }else{ int flag=0; if(argv[i][1]=='D'||argv[i][1]=='I') flag=1; for(j=0;j<MAXCF&&flag==0;j++){ size_t l; if(!c_flags_name[j]) continue; l=strlen(c_flags_name[j]); if(l>0&&!strncmp(argv[i]+1,c_flags_name[j],l)&&(argv[i][1+l]==0||argv[i][1+l]=='=')){ flag=1; if((c_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;} c_flags[j]|=USEDFLAG; if(c_flags[j]&STRINGFLAG){ if(argv[i][l+1]!='='){error(3,argv[i]);} if(argv[i][l+2]||i>=argc-1) c_flags_val[j].p=&argv[i][l+2]; else c_flags_val[j].p=&argv[++i][0]; } if(c_flags[j]&VALFLAG){ if(argv[i][l+1]!='='){error(4,argv[i]);} if(argv[i][l+2]||i>=argc-1) c_flags_val[j].l=atol(&argv[i][l+2]); else c_flags_val[j].l=atol(&argv[++i][0]); } if(c_flags[j]&FUNCFLAG) c_flags_val[j].f(&argv[i][l+1]); } } for(j=0;j<MAXGF&&flag==0;j++){ size_t l; if(!g_flags_name[j]) continue; l=strlen(g_flags_name[j]); if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){ flag=1; if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;} g_flags[j]|=USEDFLAG; if(g_flags[j]&STRINGFLAG){