Mercurial > hg > CbC > old > device
changeset 889:6a92d3e8a4b5
expr14 reorganization
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 06 Apr 2014 11:54:08 +0900 |
parents | 2466ac7c1287 |
children | 9d5da127f462 |
files | mc-inline.c mc-parse.c test/strinit.c |
diffstat | 3 files changed, 180 insertions(+), 166 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-inline.c Sun Apr 06 04:50:34 2014 +0900 +++ b/mc-inline.c Sun Apr 06 11:54:08 2014 +0900 @@ -885,7 +885,10 @@ error(-1); } e = caddr(init); - if (!e) continue; // {...,} case + if (!e) { // {...,} case, zerofill + offset = passign_data(var,EMPTY,list2(CONST,size(target_type)),EMPTY,offset); + continue; + } e = pexpr(e); offset = pdecl_data(var,car(type0),e,offset); } @@ -901,9 +904,6 @@ target_type = type_value(target_type); if (init==0) { - // empty declaration - // it can happen like a = (struct hoge){}; - // offset = passign_data(var,EMPTY,list2(CONST,size(target_type)),EMPTY,offset); return offset; } e = cadr(init);
--- a/mc-parse.c Sun Apr 06 04:50:34 2014 +0900 +++ b/mc-parse.c Sun Apr 06 11:54:08 2014 +0900 @@ -1675,7 +1675,7 @@ // local var init cannot postponed because of assign_expr0/type // if initialization contains expressions, // we cannot do it in STADECL, but we can assign later in this mode - if (local_nptr || mode==SFDINIT) { + if (local_nptr || mode==SFDINIT || inmode ) { decl_data_field(type,v,local_struct_offset); return; } @@ -4057,75 +4057,183 @@ /* term */ static int +expr_identifier() +{ + int e1; + conv->id_(sym,nptr); + switch(nptr->sc) { + case EXTRN: case EXTRN1: + extrn_use(nptr); + case STATIC: + if(is_code(nptr)||is_function(nptr)) { + return fname(nptr); + } + case GVAR: + e1=list3n(GVAR,0,nptr); + type=nptr->ty; + getsym(0); + extrn_use(nptr); + break; + case FLABEL: case BLABEL: + return fname(nptr); + case LVAR: + case IVAR: + case LREGISTER: + case DREGISTER: + case FREGISTER: + case REGISTER: + e1=list3n(nptr->sc,nptr->dsp,nptr); + type=nptr->ty; + getsym(0); + break; + case ENUM: + e1=list2(CONST,nptr->dsp); + type=INT; + getsym(0); + break; + case EMPTY: + if(getsym(0)==LPAR) { + type= glist3(stmode==GOTO?CODE:FUNCTION,INT,0); + nptr->sc = EXTRN1; + nptr->ty= type; + extrn_use(nptr); + e1=expr15(list3n(FNAME,0,nptr)); + break; + } else if (in_macro_if) { + type = INT; + e1= list2(CONST,0); + break; + } else { + if (stmode!=GOTO) // undefined on goto statement is OK + error(UDERR); + int smode = mode; mode = GDECL; + // type = nptr->ty= glist3(FUNCTION,INT,0); + type = INT; + def(nptr,0); + nptr->sc = EXTRN1; + mode = smode; + e1=list3n(FNAME,0,nptr); + // type=list3(nptr->sc,nptr->ty,nptr->dsp); + break; + } + default:error(UDERR); e1 = 0; + } + return expr16(e1); +} + +static int +typecast() +{ + int e1; + NMTBL *nptr0; + int t=typename(); + conv->type_(t,0,0); + conv->rpar_(); + checksym(RPAR); + if (sym==LC && (t>0 && (car(t)==STRUCT||car(t)==UNION))) { + // initializer + // q->lock = (spinlock_t) { }; + conv->lc_(); + nptr0 = get_nptr(); // should be freed in a scope? + // in case of inline, we cannot + nptr0->nm = ""; + nptr0->sc = EMPTY; + nptr0->attr = 0; + type = nptr0->ty = t; + def(nptr0,0); + if (mode==GDECL||inmode) { + int e2,e3; + e1 = size(type); + e2 = list3n(GVAR,0,nptr0); + e3 = decl_data_field(type,e2,0); + if (!inmode) { + e1 = list3(RSTRUCT,e2,e1); + } else { + e1 = reverse0(e3); + e1 = list3(DECL_DATA,e1,t); + e1 = list4(CAST,e1,t,t); // only for cast syntax + } + } else { + e1 = list3n(nptr0->sc,nptr0->dsp,nptr0); +#if LOCAL_STRUCT_INIT_STATIC + local_struct_static(e1); +#else + decl_data_field(type,e1,0); +#endif + } + if (init_vars && mode!=LDECL) { + emit_init_vars(); + } + conv->rc_(); + checksym(RC); + type = t; + return e1; + } + e1=expr13(); // (type) expr + if (inmode) { + e1 = list4(CAST,e1,t,type); + type = t; + return e1; + } else { + if (integral(t) || t==DOUBLE || t==FLOAT || t==LONGLONG || t==ULONGLONG) + e1 = rvalue(e1); // left value should not be rvalued + e1 = correct_type(e1,t); + type = t; + return e1; + } +} + +static int +statement_expression() +{ + // statement in expression (GNU extension) + // a = {hoge(); 1;} + // In docomp, last expression is kept in lastexp. + // + int e1; + if (inmode) { + int sparse = parse; parse=0; + docomp(1); + // wrong parse tree fix me! + e1 = list3(COMMA,reverse0(parse),lastexp); + parse = sparse; + lastexp = 0; + } else { + int l,b,l2,cntl=control; + // if COMMA expr is not gexpred by !control, + // l2 is not defined and generates undefined error. + // cntl prevents this. + if (cntl) { + gen_jmp(l=fwdlabel()); + } else l = 0; + b = backdef(); // control=1 + docomp(1); + if (cntl) { + gen_jmp(l2=fwdlabel()); + } else l2 = 0; + // make it a simple call (by jmp) + // register stack save now + e1 = list3(COMMA,list3(LCALL,b,l2),lastexp); + lastexp = 0; + if (l) fwddef(l); + control=cntl; + } + conv->rpar_(); + checksym(RPAR); + return expr16(e1); +} + +/** + * basic term + */ +static int expr14(void) { - int e1=0,t,t1,smode; - NMTBL *nptr0; + int e1=0,t,t1; switch(sym) { case IDENT: - conv->id_(sym,nptr); - switch(nptr->sc) { - case EXTRN: case EXTRN1: - extrn_use(nptr); - case STATIC: - if(is_code(nptr)||is_function(nptr)) { - return fname(nptr); - } - case GVAR: - e1=list3n(GVAR,0,nptr); - type=nptr->ty; - getsym(0); - extrn_use(nptr); - break; - case FLABEL: case BLABEL: - return fname(nptr); - case FUNCTION: case CODE: - error(-1); // FNAME have to be used - break; - case LVAR: - case IVAR: - case LREGISTER: - case DREGISTER: - case FREGISTER: - case REGISTER: - e1=list3n(nptr->sc,nptr->dsp,nptr); - type=nptr->ty; - getsym(0); - break; - case ENUM: - e1=list2(CONST,nptr->dsp); - type=INT; - getsym(0); - break; - case EMPTY: - if(getsym(0)==LPAR) { - type= glist3(stmode==GOTO?CODE:FUNCTION,INT,0); - nptr->sc = EXTRN1; - nptr->ty= type; - extrn_use(nptr); - e1=expr15(list3n(FNAME,0,nptr)); - break; - } else if (in_macro_if) { - type = INT; - e1= list2(CONST,0); - break; - } else { - if (stmode!=GOTO) // undefined on goto statement is OK - error(UDERR); - smode = mode; mode = GDECL; - // type = nptr->ty= glist3(FUNCTION,INT,0); - type = INT; - def(nptr,0); - nptr->sc = EXTRN1; - mode = smode; - e1=list3n(FNAME,0,nptr); - // type=list3(nptr->sc,nptr->ty,nptr->dsp); - break; - } - default:error(UDERR); - } - break; + return expr_identifier(); case STRINGS: e1=list3n(STRINGS,nptr->dsp,nptr); type=list3(ARRAY,CHAR,symval); @@ -4216,108 +4324,15 @@ e1=list2(CONST,lineno); getsym(0); break; - case LPAR: conv->lpar_(); getsym(0); qualifiers(); - /* type cast */ - if(typeid(sym)) { - t=typename(); - conv->type_(t,0,0); - conv->rpar_(); - checksym(RPAR); - if (sym==LC && (t>0 && (car(t)==STRUCT||car(t)==UNION))) { - // initializer - // q->lock = (spinlock_t) { }; - conv->lc_(); - if (mode==GDECL||inmode) { - int e2,e3; - smode = mode; - type = t; - nptr0=new_static_name("__lstruct",'_'); - mode=STADECL; - def(nptr0,0); - e1 = size(type); - mode = smode; - e2 = list3n(GVAR,0,nptr0); - e3 = decl_data_field(type,e2,0); - if (!inmode) { - e1 = list3(RSTRUCT,e2,e1); - } else { - e1 = reverse0(e3); - e1 = list3(DECL_DATA,e1,t); - e1 = list4(CAST,e1,t,t); // only for cast syntax - } - } else { - nptr0 = get_nptr(); // should be freed in a scope? - // in case of inline, we cannot - nptr0->nm = ""; - nptr0->sc = EMPTY; - nptr0->attr = 0; - type = nptr0->ty = t; - def(nptr0,0); - e1 = list3n(nptr0->sc,nptr0->dsp,nptr0); -#if LOCAL_STRUCT_INIT_STATIC - local_struct_static(e1); -#else - decl_data_field(type,e1,0); -#endif - } - if (init_vars && mode!=LDECL) { - emit_init_vars(); - } - conv->rc_(); - checksym(RC); - type = t; - return e1; - } - e1=expr13(); // (type) expr - if (inmode) { - e1 = list4(CAST,e1,t,type); - type = t; - return e1; - } else { - if (integral(t) || t==DOUBLE || t==FLOAT || t==LONGLONG || t==ULONGLONG) - e1 = rvalue(e1); // left value should not be rvalued - e1 = correct_type(e1,t); - type = t; - return e1; - } + return typecast(); } else if (sym==LC) { - // statement in expression (GNU extension) - // a = {hoge(); 1;} - // In docomp, last expression is kept in lastexp. - // - if (inmode) { - int sparse = parse; parse=0; - docomp(1); - // wrong parse tree fix me! - e1 = list3(COMMA,reverse0(parse),lastexp); - parse = sparse; - lastexp = 0; - } else { - int l,b,l2,cntl=control; - // if COMMA expr is not gexpred by !control, - // l2 is not defined and generates undefined error. - // cntl prevents this. - if (cntl) { - gen_jmp(l=fwdlabel()); - } else l = 0; - b = backdef(); // control=1 - docomp(1); - if (cntl) { - gen_jmp(l2=fwdlabel()); - } else l2 = 0; - // make it a simple call (by jmp) - // register stack save now - e1 = list3(COMMA,list3(LCALL,b,l2),lastexp); - lastexp = 0; - if (l) fwddef(l); - control=cntl; - } + return statement_expression(); } else { e1=expr0(); } @@ -4410,7 +4425,6 @@ /* function call - */ static int expr15(int e1)