1906 lines · 50.6 KB · C
RawDownload
/*  $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)&&reg_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.