Mercurial > hg > CbC > old > device
changeset 681:e16b34f2b386 decl-data-tree
DECL_DATA has parse tree now.
author | kono |
---|---|
date | Mon, 01 Oct 2007 01:01:47 +0900 |
parents | f536897fa3cb |
children | 639db8597a58 |
files | Changes mc-code-arm.c mc-code-mips.c mc-codegen.c mc-codegen.h mc-inline.c mc-parse.c mc-parse.h mc-tree.c mc.h |
diffstat | 10 files changed, 749 insertions(+), 264 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun Jul 29 23:09:38 2007 +0900 +++ b/Changes Mon Oct 01 01:01:47 2007 +0900 @@ -9419,8 +9419,55 @@ REGS_MAX = 128*3 ぐらいにする? - - - - - +Tue Jul 31 13:33:59 JST 2007 + +delc_data は inline tree にならない。これは、良くないので、 +一旦、parse tree に落す必要がある。 + + list(ST_DECL,next,nptr,type,(mode,smode,stmode),initialize) + initialize + list(CONST,value); =1 + list(ARRAY,next,e); ={1,2,3} + list(CAST,next,type,e); ={(struct hoge){..}) + +かな? + +decl_data_*は、offset を返すのではなくて、式を返す。 + +その式を解釈する assign_data シリーズを新しく作る。 + +(いろいろ書いているけど、進まないね〜) + +Fri Aug 3 18:06:49 JST 2007 + +CAST/DECL_DATA は、あとは、コード生成を書くだけか。 + +結局、inmode only にして書き直すのかな〜 + +Wed Sep 12 19:53:33 JST 2007 + +DECL_DATA のコード生成が全然書いてないじゃん〜 + +つうか、でたらめかも... もう少し考えないとだめだ。 + +Mon Sep 17 16:56:54 JST 2007 + +print_operator も書いてないのか。 + +Fri Sep 28 07:04:00 JST 2007 + +やっぱり、pexpr 内部で、type 大域変数にアクセスするのは、 +まずいだろ? + +Sat Sep 29 12:48:30 JST 2007 + +デバッグが果てしない... + +Sat Sep 29 14:25:41 JST 2007 + +なんか、むちゃくちゃ難しいよ... + + + + +
--- a/mc-code-arm.c Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-code-arm.c Mon Oct 01 01:01:47 2007 +0900 @@ -2198,7 +2198,7 @@ #endif -static void +void use_reg(int arg) { // printf("## use reg %d\n",arg); @@ -2219,7 +2219,7 @@ } } -static void +void code_save_input_registers(int dots) { int args; @@ -2283,7 +2283,7 @@ return 0; } -static int +int simple_arg(int e3) { return !contains_p(e3,not_simple_p);
--- a/mc-code-mips.c Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-code-mips.c Mon Oct 01 01:01:47 2007 +0900 @@ -1796,7 +1796,7 @@ #endif -static void +void use_reg(int arg) { // printf("## use reg %d\n",arg); @@ -1817,7 +1817,7 @@ } } -static void +void code_save_input_registers(int dots) { int args; @@ -1904,19 +1904,19 @@ return 0; } -static int +int simple_arg(int e3) { return !contains_p(e3,not_simple_p); } -static int +int caller_arg_offset_v(int arg) { return ARG_LVAR_OFFSET+arg*SIZE_OF_INT; } -static void +void use_input_reg(int reg,int mode) { if (is_int_reg(reg)) {
--- a/mc-codegen.c Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-codegen.c Mon Oct 01 01:01:47 2007 +0900 @@ -60,6 +60,7 @@ static int register_to_lvar(int e); static void remove0(int *parent,int e) ; static void sassign(int e1); +static int gen_decl_data(int e); #if FLOAT_CODE @@ -292,7 +293,7 @@ case ARRAY: if (chk==2) { g_expr0(e2); - t = g_expr0(caddr(e1)); + g_expr0(caddr(e1)); code_gexpr(e1); return t; } @@ -575,7 +576,6 @@ code_environment(USE_CREG); return ADDRESS; case LCALL: - // we cannot trust register variable either... code_save_stacks(); gen_jmp(e2); fwddef(caddr(e1)); @@ -601,6 +601,13 @@ /* asm in (str) out (str) opt(str) expr */ return VOID; #endif + case CAST: + type = cadddr(e1); + e2 = correct_type(e2,caddr(e1)); + continue; + case DECL_DATA: + e1 = gen_decl_data(e1); + return e1; case ST_DECL: st_decl(e1); break; case ST_IF: st_if(e1); break; case ST_DO: st_do(e1); break; @@ -2823,30 +2830,31 @@ contains_p(int e,int (*p)(int)) { while(e) { - if (!car(e)) return 0; - if (p(car(e))) return 1; - if (LIST_ARGS(car(e))){ + int e1 = car(e); + if (!e1) return 0; + if (p(e1)) return 1; + if (LIST_ARGS(e1)){ /* list arguments */ return contains_in_list_p(caddr(e),p); - } else if (UNARY_ARGS(car(e))) { + } else if (UNARY_ARGS(e1)) { /* unary operators */ e = cadr(e); continue; - } else if (BINARY_ARGS(car(e))) { + } else if (BINARY_ARGS(e1)) { /* biary operators */ if (contains_p(cadr(e),p)) return 1; e = caddr(e); continue; - } else if (TERNARY_ARGS(car(e))) { + } else if (TERNARY_ARGS(e1)) { /* tarary operators */ if (contains_p(cadr(e), p)) return 1; if (contains_p(caddr(e),p)) return 1; e = cadddr(e); continue; - } else if (NULLARY_ARGS(car(e))) { + } else if (NULLARY_ARGS(e1)) { /* nullary operators */ return 0; - } else if (IS_STATEMENT(car(e))) { + } else if (IS_STATEMENT(e1)) { return 1; // may contain anything } else { // if (lsrc)fprintf(stderr,"Unknown Tree ID %d\n",car(e)); @@ -2873,30 +2881,31 @@ contains_p1(int arg,int e,int (*p)(int,int)) { while(e) { - if (!car(e)) return arg; - if (LIST_ARGS(car(e))){ + int e1 = car(e); + if (!e1) return arg; + if (LIST_ARGS(e1)){ /* list arguments */ return contains_in_list_p1(arg,caddr(e),p); - } else if (UNARY_ARGS(car(e))) { + } else if (UNARY_ARGS(e1)) { /* unary operators */ e = cadr(e); continue; - } else if (BINARY_ARGS(car(e))) { + } else if (BINARY_ARGS(e1)) { /* biary operators */ arg=contains_p1(arg,cadr(e),p); e = caddr(e); continue; - } else if (TERNARY_ARGS(car(e))) { + } else if (TERNARY_ARGS(e1)) { /* tarary operators */ arg=contains_p1(arg,cadr(e), p); arg=contains_p1(arg,caddr(e),p); e = cadddr(e); continue; - } else if (NULLARY_ARGS(car(e))) { + } else if (NULLARY_ARGS(e1)) { /* nullary operators */ arg=p(arg,e); return arg; - } else if (IS_STATEMENT(car(e))) { + } else if (IS_STATEMENT(e1)) { return arg; } else { // if (lsrc)fprintf(stderr,"Unknown Tree ID %d\n",car(e)); @@ -3433,7 +3442,7 @@ return; } while(e) { - gexpr(car(e),0); + g_expr_u(car(e)); e = cadr(e); } } @@ -3523,6 +3532,160 @@ error(INERR); } +static int gen_decl_data0(NMTBL *nptr0,int target_type,int init,int offset); + +extern int +gen_delayed_decl_data(NMTBL *n,int offset) +{ + int offset0=0; + int e; + int t,sz,offset1=0; + int init = decl_str_init; + + decl_str_init = 0; + sz = size(n->ty); + /* + decl_str_init + output delayed decl data + list4(offset,next,expression,list2(type0,type1)); + */ + while (init) { + offset= car(init); + e=caddr(init); + t=car(cadddr(init)); + if (offset!=offset0) { + // make space + assign_data(list2(CONST,offset-offset0),EMPTY,n,offset0); + } + type=cadr(cadddr(init)); + offset0 = gen_decl_data0(n,t,e,offset); + init = cadr(init); + } + offset = offset0; + if ((sz=(offset1+sz-offset))>0) + assign_data(list2(CONST,sz),EMPTY,n,offset0); + decl_str_init = 0; + local_nptr = 0; + return offset; +} + +static int +gen_decl_data_array(NMTBL *nptr0,int init,int target_type,int offset) +{ + int type0 = cadr(target_type); /* array item type */ + int e; + + for(; init; init = cadr(init)) { + // unordered data with tag or array offset + if (car(init)!=DECL_DATA_ARRAY) { + error(-1); + } + e = pexpr(caddr(init)); + offset = gen_decl_data0(nptr0,type0,e,offset); + } + return offset; +} + +static int +gen_decl_data_field(NMTBL *nptr0,int init,int target_type,int offset) +{ + int type0 = target_type; /* list of fields */ + int e,t,type1,foffset; + NMTBL *n; + + for(; init; init = cadr(init)) { + // unordered data with tag or array offset + if (car(init)!=DECL_DATA_FIELD) { + error(-1); + } + n = (NMTBL*)cadddr(init); + type1 = search_struct_type(type0,n->nm,&foffset); + e = caddr(init); + if (car(e)!=DECL_DATA) error(-1); + t = caddr(e); + decl_str_init=insert_ascend(decl_str_init, + glist4(offset+foffset,0,e,glist2(type1,t)),str_init_eq); + } + return offset; +} + +static int +gen_decl_data_list(NMTBL *nptr0,int init,int target_type,int offset) +{ + int type0 = caddr(target_type); /* list of fields */ + int e; + + for(; init; init = cadr(init)) { + // ordered data + if (car(init)!=DECL_DATA_LIST) { + error(-1); + } + e = caddr(init); + offset = gen_decl_data0(nptr0,car(type0),e,offset); + type0 = cadr(type0); + } + return offset; +} + + +static int +gen_decl_data0(NMTBL *nptr0,int target_type,int init,int offset) +{ + int e,t; + if (car(init)==DECL_DATA) { + switch( car(e=cadr(init))) { + case DECL_DATA_LIST: + offset = gen_decl_data_list(nptr0,e,target_type,offset); + break; + case DECL_DATA_FIELD: + offset = gen_decl_data_field(nptr0,e,target_type,offset); + break; + case DECL_DATA_ARRAY: + offset = gen_decl_data_array(nptr0,e,target_type,offset); + break; + default: + t = caddr(init); // type of source + e = rvalue_t(e,t); + offset=assign_data(e,t,nptr0,offset); + } + } else { + error(-1); + } + if (decl_str_init) { + offset = gen_delayed_decl_data(nptr0,offset); + } + return offset; +} + +static int +gen_decl_data(int e) +{ + NMTBL *nptr0; + int t = caddr(e); + int e1,sz; + int offset = 0; + int sinit_vars = init_vars; + init_vars = 0; + + nptr0 = get_nptr(); + nptr0->nm = ""; + nptr0->sc = LVAR; + nptr0->attr = 0; + type = nptr0->ty = t; + sz = size(type); + nptr0->dsp = new_lvar_align(sz,16); + + e1 = list3(RSTRUCT,list3( + nptr0->sc,nptr0->dsp,(int)nptr0),sz); + + gen_decl_data0(nptr0,t,e,offset); + + if (init_vars) emit_init_vars(); + g_expr0(e1); + init_vars = sinit_vars; + return type; +} + // // local variable initialization // @@ -3532,6 +3695,7 @@ { int ass,sz,bfd; + if (inmode) error(-1); #if STRUCT_ALIGN if (t!=-99) { int strtype=0; @@ -3550,10 +3714,20 @@ error(TYERR); } } - if(mode==GDECL) { + switch (mode) { + case GDECL: if (!is_const(e)) error(INERR); emit_data(e,t,n); - } else if(mode==LDECL || (mode==STADECL&&local_nptr&&(n=local_nptr))) { + break; + case STADECL: + if (!local_nptr) { + if (!is_const(e)) error(INERR); + else emit_data(e,t,n); + break; + } + n = local_nptr; + case LDECL: + case STAT: // inline case if (t==EMPTY) { /* empty space in partial initialization */ return offset+cadr(e); @@ -3569,16 +3743,15 @@ (n->sc==REGISTER||n->sc==DREGISTER||n->sc==FREGISTER||n->sc==LREGISTER)? list3(n->sc,n->dsp,(int)n): list3(n->sc,n->dsp+offset,(int)n), - e,t,type); + e,t,type); init_vars = list2(ass,init_vars); - } else if(mode==STADECL) { - if (!is_const(e)) error(INERR); - else emit_data(e,t,n); - } else if(mode==SFDINIT) { + break; + case SFDINIT: // if (lsrc)printf("## %d sfdinit c0(e)=%d type=%d t=%d offset=%d\n",lineno,car(e),type,t,offset); decl_str_init=insert_ascend(decl_str_init, glist4(offset,0,e,glist2(t,type)),str_init_eq); - } else { + break; + default: error(DCERR); return offset; } @@ -3605,8 +3778,6 @@ int offset0=0; int e; int t,sz,offset1=0; - int smode=mode; - mode = STADECL; sz = size(n->ty); /* decl_str_init @@ -3631,14 +3802,15 @@ assign_data(list2(CONST,sz),EMPTY,n,offset0); decl_str_init = 0; local_nptr = 0; - mode=smode; } extern void data_closing(NMTBL *n) { if (!chk) { + int smode = mode; mode = STADECL; if (decl_str_init) flush_delayed_decl_data(n); + mode = smode; emit_data_closing(n); } } @@ -3779,22 +3951,29 @@ } } -static void -compatible(int t1, int t2) +extern int +type_compatible(int t1, int t2) { t1 = type_value(t1); t2 = type_value(t2); if(integral(t1)) { - if(t1!=t2) error(TYERR); + if(t1!=t2) return 0; } else if(t1<0 || t2<0) { - if(t1!=t2) error(TYERR); + if(t1!=t2) return 0; } else if(car(t1)!=car(t2)) - error(TYERR); + return 0; else if((car(t1)==STRUCT || car(t1)==UNION) && cadr(t1)!=cadr(t2)) - error(TYERR); + return 0; else if(car(t1)==POINTER || car(t1)==ARRAY ||car(t1)==FUNCTION) - compatible(cadr(t1),cadr(t2)); + return type_compatible(cadr(t1),cadr(t2)); + return 1; +} + +static void +compatible(int t1, int t2) +{ + if (!type_compatible(t1,t2)) error(TYERR); } extern int @@ -4070,7 +4249,7 @@ { int dsp = 0; int type0; - int e1 = 0; + int e1; if (inmode || chk) { e1 = list4(ind?ARROW:PERIOD,e,(int)nptr,type); @@ -4086,7 +4265,7 @@ /* type = list4(s,disp,fields,tag_nptr); */ /* print_fields(caddr(type),"strop"); */ type = search_struct_type(type,nptr->nm,&dsp); - if (!type) { error(TYERR); type=INT; return e; } + if (!type) { error(UFLDERR); type=INT; return e; } if (inmode || chk) { // bitfield will be checked after parse return e1;
--- a/mc-codegen.h Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-codegen.h Mon Oct 01 01:01:47 2007 +0900 @@ -97,12 +97,14 @@ extern void gen_label_call(int l); extern void flush_delayed_decl_data(NMTBL *n); + /* used by mc-inline */ extern void checkjmp(int l); // generate delayed jump, l = current label extern int reference(int e1); // recover lvalue from rvalue of memory or register extern int type_of_bop(int op); extern int type_of_conv(int op); +extern int type_compatible(int t1, int t2); /* used by mc-code-* */
--- a/mc-inline.c Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-inline.c Mon Oct 01 01:01:47 2007 +0900 @@ -672,19 +672,219 @@ return list4(car(e),pexpr(cadr(e)),e1,cadddr(e)); } +/* + variable initialization with offset + */ + +static int +passign_data(int var,int target_type, int e,int t,int offset) +{ + int ass,sz,bfd; + +#if STRUCT_ALIGN + if (t!=-99) { + int strtype=0; + if (t>0 && (car(t)==STRUCT||car(t)==UNION)) + strtype=1; + sz = size(t); + if (sz%size_of_int==0||strtype) { + offset = ((offset+(size_of_int-1))&~(size_of_int-1)); + } + } +#endif + if (car(e)==ADDRESS||car(e)==GVAR) { + if (scalar(t)) { + t = list2(POINTER,VOID); // fake + } else { + error(TYERR); + } + } + if (t==EMPTY) { + /* empty space in partial initialization */ + return offset+cadr(e); + } + type = t; + e = rvalue_t(e,t); + if (!scalar(type) && (type>0 && (car(type)!=ADDRESS && car(type)!=ARRAY))) + e = correct_type(e,target_type); + /* If this is a local declared constant, we don't have to assign. + But some one may take it's address. We have to generate assign. + */ + ass = assign_expr0( + offset? + list3(ADD,var,list2(CONST,offset)): + var, + e,target_type,t); // already correct_typed + init_vars = list2(ass,init_vars); + if (t>0&&car(t)==BIT_FIELD) { + sz = 0; + bfd = cadr(caddr(t)); /* bit_field_disp */ +#if BIT_FIELD_CODE + code_bit_field_disp(t,&offset,&bfd,&sz); +#endif + return offset+sz; + } + return offset+((t==EMPTY)?cadr(e):size(t)); +} + +static int pdecl_data(int var, int target_type, int init,int offset); + +static void +pflush_decl_data(int var,int sz) +{ + int offset; + int offset0=0; + int e; + int t,offset1=0; + int smode=mode; + int init = decl_str_init; + + decl_str_init = 0; + mode = STADECL; + /* + decl_str_init + output delayed decl data + list4(offset,next,expression,list2(type0,type1)); + */ + while (init) { + offset= car(init); + e=caddr(init); + t=car(cadddr(init)); // type of source + type=cadr(cadddr(init)); // destination type + if (offset!=offset0) { + // make space + passign_data(var,EMPTY,list2(CONST,offset-offset0),EMPTY,offset0); + } + e = pexpr(e); + // offset0 = passign_data(var,type,e,t,offset); + offset0 = pdecl_data(var,type,e,offset); + init = cadr(init); + } + offset = offset0; + if ((sz=(offset1+sz-offset))>0) + passign_data(var,EMPTY,list2(CONST,sz),EMPTY,offset0); + local_nptr = 0; + mode=smode; +} + +static int +str_init_eq() +{ + // error(-1); // duplicate struct field value + return 2; // allow override keep unique +} + + +static int +pdecl_data_array(int var,int init,int target_type,int offset) +{ + int type0 = cadr(target_type); /* array item type */ + int e; + + for(; init; init = cadr(init)) { + // unordered data with tag or array offset + if (car(init)!=DECL_DATA_ARRAY) { + error(-1); + } + e = pexpr(caddr(init)); + offset = pdecl_data(var,type0,e,offset); + } + return offset; +} + +static int +pdecl_data_field(int var,int init,int target_type,int offset) +{ + int type0 = target_type; /* list of fields */ + int e,t,type1,foffset; + NMTBL *n; + + for(; init; init = cadr(init)) { + // unordered data with tag or array offset + if (car(init)!=DECL_DATA_FIELD) { + error(-1); + } + n = (NMTBL*)cadddr(init); + type1 = search_struct_type(type0,n->nm,&foffset); + e = caddr(init); + if (car(e)!=DECL_DATA) error(-1); + t = caddr(e); + decl_str_init=insert_ascend(decl_str_init, + glist4(offset+foffset,0,e,glist2(type1,t)),str_init_eq); + } + return offset; +} + +static int +pdecl_data_list(int var,int init,int target_type,int offset) +{ + int type0 = caddr(target_type); /* list of fields */ + int e; + + for(; init; init = cadr(init)) { + // ordered data + if (car(init)!=DECL_DATA_LIST) { + error(-1); + } + e = pexpr(caddr(init)); + offset = pdecl_data(var,car(type0),e,offset); + type0 = cadr(type0); + } + return offset; +} + +static int +pdecl_data(int var, int target_type, int init,int offset) +{ + int t,e; + int save_decl_str_init = decl_str_init; + decl_str_init = 0; + target_type = type_value(target_type); + + if (car(init)==DECL_DATA) { + switch( car(e=cadr(init))) { + case DECL_DATA_LIST: + offset = pdecl_data_list(var,e,target_type,offset); + break; + case DECL_DATA_FIELD: + offset = pdecl_data_field(var,e,target_type,offset); + break; + case DECL_DATA_ARRAY: + offset = pdecl_data_array(var,e,target_type,offset); + break; + default: + e = pexpr(e); + t = caddr(init); // type of source + offset = passign_data(var,target_type,e,t,offset); + } + } else { + error(-1); + } + if (decl_str_init) { + int sz = size(target_type); + pflush_decl_data(var,sz); + } + decl_str_init = save_decl_str_init; + return offset; +} + // handle local variable declaration -// initialization is accumrated in parse tree +// initialization is accumrated in init argument // should consider int k=some_compile_time_constant; static int p_decl(int e) { - // list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode)); + // list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode),init); int ctmode=cadddr(e); NMTBL *n=(NMTBL*)caddr(e); int dsp = n->dsp; int v=0; int sstmode = stmode; int smode = mode; + int save_init_vars = init_vars; + int init = caddddr(e); // variable initialization + + init_vars = 0; // in real partial evaluation, we have to check whether this variable // is used or not. if (ctmode) { @@ -696,8 +896,10 @@ case EXTRN: case EXTRN1: case STATIC: // def(n,ctmode); we don't need this. already done. // stmode = sstmode; + if (init) error(-1); stmode = sstmode; mode = smode; + init_vars = save_init_vars; return pexpr(cadr(e)); // case LLDECL: LLDECL is mode, not stmode (bad design) // v = list2(FLABEL,fwdlabel()); break; @@ -733,6 +935,20 @@ heap[pdisp+dsp]=v; stmode = sstmode; mode = smode; + if (init) { + pdecl_data(v,n->ty,init,0); + if (init_vars) { + int e1 = pexpr(cadr(e)); + init_vars = reverse0(init_vars); + while (init_vars) { + e1 = list3(ST_COMP,e1,car(init_vars)); + init_vars = cadr(init_vars); + } + init_vars = save_init_vars; + return e1; + } + } + init_vars = save_init_vars; return pexpr(cadr(e)); } @@ -1182,6 +1398,21 @@ car(e2),cadr(e2),caddr(e2),cadddr(e2)), caddr(e1)); #endif + case CAST: + if (car(e2)==DECL_DATA) { + // casted initialized structure (struct hoge){...} + return list3(DECL_DATA,pexpr(cadr(e2)),caddr(e2)); + } + if (type_compatible(caddr(e1),cadddr(e1))) { + return pexpr(e2); + } else + return list4(CAST,pexpr(e2),caddr(e1),cadddr(e1)); + case DECL_DATA: + return list3(DECL_DATA,pexpr(e2),caddr(e1)); + case DECL_DATA_LIST: + return list4(DECL_DATA_LIST,pexpr(e2),pexpr(caddr(e1)),cadddr(e1)); + case DECL_DATA_FIELD: + return list4(DECL_DATA_FIELD,pexpr(e2),pexpr(caddr(e1)),cadddr(e1)); case ST_DECL: return p_decl(e1); case ST_IF: return p_if(e1); case ST_DO: return p_do(e1);
--- a/mc-parse.c Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-parse.c Mon Oct 01 01:01:47 2007 +0900 @@ -219,7 +219,6 @@ static int ac,ac2; static char **av; -extern int gdb(int a,int b,const char *c); int main(int argc, char **argv) @@ -461,6 +460,7 @@ (n==UFERR) ? "already used as function" : (n==ENERR) ? "function has return value but reached to the end" : (n==CSERR) ? "no excutable code in switch" : + (n==UFLDERR) ? "unknown field in struct/union" : (n==RETERR) ? "return in code segement is not allowed" : "Bug of compiler"); errmsg(); @@ -519,7 +519,10 @@ heap_init() { gpc=glineno=0; - if (!heap) heap = (int *)malloc(heapsize*sizeof(int)); + if (!heap) { + heap = (int *)malloc(heapsize*sizeof(int)); + heap[0] = 0; // car(0) case + } if (!heap) error(MMERR); gfree=1; labelno=2; @@ -617,7 +620,6 @@ reserve("__builtin_inf",BUILTIN_INF,RESERVE); reserve("__builtin_inff",BUILTIN_INFF,RESERVE); reserve("__builtin_infl",BUILTIN_INFL,RESERVE); -// reserve("__builtin_type_is_float",BUILTIN_IS_FLOAT,RESERVE); reserve("__attribute__",ATTRIBUTE,RESERVE); reserve("__attribute",ATTRIBUTE,RESERVE); reserve("__label__",LABEL,RESERVE); @@ -924,16 +926,18 @@ fdecl(n); return; } else error(DCERR); } else { + int init = 0; conv->return_type_(type,n,sd); n = def(n,ctmode); - if (inmode==INLINE && (mode==LDECL||mode==LLDECL)) { - parse = list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode)); - } if (sym==ASS && n!=&null_nptr) { conv->op_(sym); - decl_data(type,n,0,0); data_closing(n); + init = decl_data(type,n,0,0); data_closing(n); + } + if (inmode && (mode==LDECL||mode==LLDECL)) { + parse = list5(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode),init); } while(sym==COMMA) { + init = 0; conv->comma_(); getsym(0); type=t; @@ -946,12 +950,13 @@ } conv->return_type_(type,n,1); def(n,ctmode); - if (inmode==INLINE && mode==LDECL) { - parse = list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode)); - } if (sym==ASS && n!=&null_nptr) { conv->op_(sym); - decl_data(type,n,0,0);data_closing(n); + init = decl_data(type,n,0,0);data_closing(n); + } + if (inmode && mode==LDECL) { + parse = list5(ST_DECL,parse,(int)n, + list3(mode,stmode,ctmode),init); } } if(sym!=SM) error(DCERR); @@ -1216,16 +1221,7 @@ if(sym==LBRA) { /* array */ if(getsym(0)==RBRA) { getsym(0); - if(mode==ADECL) { - type=list3(ARRAY,type,0); - } else if (mode==GDECL || stmode==EXTRN) { - type=list3(ARRAY,type,0); - } else if (mode==GSDECL || mode==LSDECL) { - // flexible array members - type=list3(ARRAY,type,0); - } else { - error(DCERR); - } + type=list3(ARRAY,type,0); } else { array_type=type; i=cexpr(expr(1)); @@ -1523,6 +1519,8 @@ t = typename(); checksym(RPAR); offset = decl_data(t,n,offset,1); + if (inmode) + offset = list4(CAST,offset,t,type); } else { return 0; } @@ -1537,6 +1535,7 @@ // int offset0 = offset+size(type); int mode_save=mode; int type0=type_value(type); + NMTBL *nptr1; if(cadr(type0)==-1) { // no struct field defenition error(DCERR); @@ -1549,7 +1548,7 @@ } else if (sym==LPAR) { // have to be a value, no comma cascading values // .__tcp_lhash_lock = (rwlock_t) { }, - // We cannot this distinguish this case and cascading comma here. + // We cannot distinguish this case and cascading comma here. // Do it more upper syntactical node; if ((offset = decl_data_1(type,n,offset))) { return offset; @@ -1564,10 +1563,17 @@ period=1; getsym(0); if (sym==IDENT) { - t2 = search_struct_type(type,nptr->nm,&foffset); + nptr1 = nptr; + t2 = search_struct_type(type,nptr1->nm,&foffset); + if (!t2) error(UFLDERR); getsym(0); if (sym==ASS) { - decl_data(t2,n,offset+foffset,0); + if (inmode) { + int offset1 = decl_data(t2,n,0,0); + offset = list4(DECL_DATA_FIELD,offset,offset1,(int)nptr1); + } else { + decl_data(t2,n,offset+foffset,0); + } } else error(INERR); } else @@ -1579,7 +1585,12 @@ } if(!t1) break; // empty field case (it can happen...) // next decl_data must skip getsym - offset = decl_data(car(t1),n,offset,1); /* alignment? */ + if (inmode) { + int offset1 = decl_data(car(t1),n,0,1); /* alignment? */ + offset = list4(DECL_DATA_LIST,offset,offset1,car(t1)); + } else { + offset = decl_data(car(t1),n,offset,1); /* alignment? */ + } t1 = cadr(t1); } if ( t1 && sym==COMMA) { conv->comma_(); getsym(0); continue; } @@ -1592,6 +1603,9 @@ #if LOCAL_STRUCT_INIT_STATIC + +// should be in mc-codegen.c + static void local_struct_static(NMTBL *n) { @@ -1602,6 +1616,8 @@ // 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 (inmode) error(-1); + if (local_nptr) error(-1); local_nptr = n; // will be clear in flush @@ -1623,6 +1639,7 @@ list3(LVAR,n->dsp+offset,0), list3(RSTRUCT,list3(GVAR,0,(int)nptr0),sz),sz), init_vars); + mode=STADECL; flush_delayed_decl_data(nptr0); mode = smode; } @@ -1630,6 +1647,21 @@ /* data structure initialization + + int a = 1; + int b[] = {1,2,3}; + struct s s = {1,2,{2,3}}; + struct s s = {.a=1,.b=2}; + struct s s = {.a=(struct b){1,2,.b=3}}; + + list item + list4(DECL_DATA_LIST,next,value,type); // coarsed later + list item with struct tag or array tag + list4(DECL_DATA_FIELD,next,decl_data,(int)nptr); + data initializer (array or struct) // data type for field + list3(DECL_DATA,value,type); + + cast 阪 */ static int @@ -1662,6 +1694,11 @@ e=expr1(); if (lc) checksym(RC); mode = mode_save; + if (inmode) { + offset = list3(DECL_DATA,e,type); + type=t; + return offset; + } //if(car(e)!=CONST && t==CHAR) // error(TYERR); // correct_type is too weak, should handle ADDRESS/ARRAY @@ -1676,12 +1713,19 @@ e=expr1(); if (lc) checksym(RC); mode = mode_save; + if (inmode) { + offset = list3(DECL_DATA,e,type); + type=t; + return offset; + } e = correct_type(rvalue(e),t0); offset = assign_data(e,t,n,offset); type=t; return offset; } else if (t0>0 && (t1 = car(t0)) && t1==ARRAY) { if (sym==LC) { + int offset1 = 0; + // int a[] = {... } conv->lc_(); conv->decl_data_begin_(); mode = mode_save; @@ -1689,9 +1733,15 @@ i = 0; for(;;) { if (sym!=RC) { - offset0 = offset; - offset=decl_data(t1,n,offset,0); /* array of some thing */ - if (offset0!=offset) i++; + if (inmode) { + int e=decl_data(t1,n,0,0); + offset1 = list4(DECL_DATA_ARRAY,offset1,e,t1); + } else { + offset0 = offset; + /* array of some thing */ + offset=decl_data(t1,n,offset,0); + if (offset0!=offset) i++; + } } if (sym==COMMA) { conv->comma_(); @@ -1699,6 +1749,12 @@ } else if (sym==RC) { conv->decl_data_end_(); conv->rc_(); + if (inmode) { + getsym(0); + offset1 = reverse0(offset1); + offset = list3(DECL_DATA,offset1,t); + return offset; + } if (caddr(t)==0) { /* size not defined */ caddr(t)=i; /* define array size */ } else if (caddr(t)!=i) { /* size match? */ @@ -1718,6 +1774,10 @@ mode = mode_save; if(car(e)!=STRING) error(TYERR); + if (inmode) { + offset = list3(DECL_DATA,e,type); + return offset; + } offset=assign_data(e,list3(ARRAY,CHAR,size(type)),n,offset); if (caddr(t0)==0) { /* size not defined */ caddr(t0)=size(type); /* define array size */ @@ -1731,28 +1791,44 @@ return offset; } } else if (t1==BIT_FIELD) { + /* + Calculation of bitfiled in compile runtime is too difficult. + */ + if(mode==GDECL) error(INERR); e=expr1(); mode = mode_save; // e = correct_type(e,t); correct me + if (inmode) { + offset = list3(DECL_DATA,e,type); + type=t; + return offset; + } offset = assign_data(e,t,n,offset); type=t; return offset; } else if (t1==STRUCT||t1==UNION) { + // struct hoge a = {...} if (sym==LC) lc=1; conv->lc_(); conv->decl_data_begin_(); mode = mode_save; #if LOCAL_STRUCT_INIT_STATIC - if(mode==LDECL) { + if(mode==LDECL && !inmode) { if (offset) error(-1); local_struct_static(n); // change mode to STADECL // decl_data_field(t,n,offset) is called inside; } else #endif + if (inmode) { + int offset1=decl_data_field(t,n,0); + offset1 = reverse0(offset1); + offset=list3(DECL_DATA,offset1,t); + } else { offset=decl_data_field(t,n,offset); + } conv->decl_data_end_(); conv->rc_(); if (lc) { - while (sym==COMMA) getsym(0); + while (sym==COMMA) getsym(0); // why we need this?! checksym(RC); } return offset; @@ -2042,16 +2118,15 @@ arg_disp = args; args = 0; disp=0; - control=1; - if (!inmode) { + if (!inmode) arg_register(fnptr); - } typedefed=0; conv->function_(fnptr,sd); conv->lc_(); init_vars=0; /* local variable declaration */ local_decl(1); + control=1; cslabel = -1; if (!inmode && !chk) gen_enter1(); emit_init_vars(); @@ -2136,7 +2211,6 @@ tmp_struct = 0; disp=0; - control=1; arg_register(fnptr); // should fix n1->dsp // make calling argments @@ -2155,8 +2229,10 @@ if(!chk) gen_enter1(); + control=1; cslabel = -1; + mode = STAT; if(!chk) gen_inline(e); if(!chk) gen_leave(control,n->nm); @@ -2287,8 +2363,7 @@ pparse = parse; parse = 0; l1 = if0 = expr(0); } else { - if0 = expr(0); - l1 = bexpr(if0,0,fwdlabel()); + l1 = bexpr((if0 = expr(0)),0,fwdlabel()); } set_lfree(slfree); conv->if_then_(if0); @@ -3530,7 +3605,7 @@ e=expr0(); checksym(RPAR); type=INT; - if (inmode==INLINE) + if (inmode) return list2(BUILTINP,rvalue(e)); /* evalue it later */ else return list2(CONST,is_const(e)); @@ -3592,46 +3667,6 @@ type = DOUBLE; e = list2(op,0); return e; -#if 0 - case BUILTIN_IS_FLOAT: - conv->prefix_(sym); - if(getsym(0)==LPAR) { - conv->lpar_(); - if(typeid(getsym(0))) { - int smode = mode; mode = LDECL; - t=typename(); - checksym(RPAR); - conv->type_(t); - conv->rpar_(); - mode = smode; - } else { - e=expr0(); - checksym(RPAR); - expr16(e); - if(sym==INC||sym==DEC) { - /* after this operation, type is extended */ - getsym(0); - switch(type) { - case CHAR: type=INT; break; - case SHORT: type=INT; break; - case UCHAR: type=UNSIGNED; break; - case USHORT: type=UNSIGNED; break; - case FLOAT: - case DOUBLE: break; - default: - if(!scalar(type)) - error(TYERR); - } - } - t = type; - conv->rpar_(); - } - } else { - expr13(); t = type; - } - type=INT; - return list2(CONST,(t==FLOAT || t==DOUBLE)); -#endif case SIZEOF: conv->prefix_(sym); if(getsym(0)==LPAR) { @@ -3688,7 +3723,7 @@ nptr1->sc=EMPTY; nptr1=l_top_search(nptr->nm,0); nptr1->sc = FLABEL; - if (!inmode) + if (inmode!=INLINE) nptr1->dsp = fwdlabel(); else nptr1->dsp = --disp; @@ -3955,6 +3990,11 @@ mode = smode; decl_data_field(type,nptr0,0); e1 = list3(RSTRUCT,list3(GVAR,0,(int)nptr0),e1); + } else if (inmode) { + e1 = decl_data_field(t,&null_nptr,0); + e1 = reverse0(e1); + 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 @@ -3962,15 +4002,12 @@ nptr0->sc = EMPTY; nptr0->attr = 0; type = nptr0->ty = t; + e1 = size(type); def(nptr0,0); - if (inmode==INLINE) { - parse = list4(ST_DECL,parse,(int)nptr0, - list3(mode,0,0)); - } #if LOCAL_STRUCT_INIT_STATIC local_struct_static(nptr0); #else - decl_data_field(type,nptr0,0); + decl_data_field(type,nptr0,0,0); #endif e1 = list3(RSTRUCT,list3( nptr0->sc,nptr0->dsp,(int)nptr0),e1); @@ -3984,7 +4021,12 @@ return e1; } e1=expr13(); - return correct_type(e1,t); + if (inmode) { + e1 = list4(CAST,e1,t,type); + type = t; + return e1; + } else + return correct_type(e1,t); } else if (sym==LC) { // statement in expression (GNU extension) // a = {hoge(); 1;} @@ -4012,24 +4054,20 @@ } else l2 = 0; // make it a simple call (by jmp) // register stack save now - // we cannot trust register variable (used as temorary) - // either, save these register is necessary... e1 = list3(COMMA,list3(LCALL,b,l2),lastexp); lastexp = 0; if (l) fwddef(l); control=cntl; #else - int smode=mode; // we already have parse tree mode, why don't we? int sparse = parse; parse=0; inmode = INLINE+1; // this does not work well... we need some work later docomp(1); - inmode = 0; mode=GDECL; - e1 = list3(COMMA,pexpr(reverse0(parse)),lastexp); - mode = smode; + e1 = list3(COMMA,reverse0(parse),lastexp); parse = sparse; lastexp = 0; + inmode = 0; #endif } } else { @@ -4114,9 +4152,9 @@ } } else { tmp_struct = def(0,0); - if (inmode==INLINE) { + if (inmode) { set_attr(tmp_struct,HAS_ADDRESS,1); - parse = list4(ST_DECL,parse,(int)tmp_struct,list3(LDECL,0,0)); + parse = list5(ST_DECL,parse,(int)tmp_struct,list3(LDECL,0,0),0); } } return tmp_struct; @@ -4882,7 +4920,6 @@ free_nptr(NMTBL *n) { n->dsp = (int)free_nptr_list; - n->sc = 0; free_nptr_list = n; } @@ -4965,6 +5002,7 @@ { int ns; NMTBL *n; + for(ns=hash->dsp;ns;ns=cadr(ns)) { if (car(ns)==sc) { return (NMTBL*)caddr(ns); @@ -5009,7 +5047,6 @@ car(current_scope) = glist3(ns,car(current_scope),(int)nptr1); caddr(ns) = (int)(nptr1 = get_nptr()); nptr1->nm = nlist->nm; nptr1->sc=EMPTY; nptr1->dsp = 0; - break; } } return nptr1; @@ -5027,7 +5064,6 @@ car(scope) = glist3(ns,car(scope),(int)nptr1); caddr(ns) = (int)(nptr1 = get_nptr()); nptr1->nm = nlist->nm; nptr1->sc=EMPTY; nptr1->dsp = 0; - break; } } return nptr1; @@ -5051,13 +5087,7 @@ ns = (NMTBL *)caddr(car(scope)); switch(ns->sc) { case GVAR: case STATIC: case IVAR: break; - default: if (!inmode) { - if (sym==IDENT && ns==nptr) { - // this is already read aheaded, replace it - nptr = (NMTBL*)caddr(scope); - } - free_nptr(ns); - } + default: if (!inmode) free_nptr(ns); } caddr(car(scope)) = caddr(scope); next = cadr(scope); @@ -5233,6 +5263,7 @@ list2(int e1, int e2) { int e; + e=getfree(2); heap[e]=e1; heap[e+1]=e2; @@ -5303,7 +5334,6 @@ return e; } - extern int glist2(int e1,int e2) { @@ -5675,18 +5705,4 @@ extern char *cc3(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)cadddr(d); } extern char *cc4(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)caddddr(d); } -int -gdb(int h,int l,const char *name) { - static int counter; - if (heap[h]>1200) return h; - if (heap[h+1]>1200) - fprintf(stderr, "gdb %d: heap[%d]=%d at %s:%d\n",counter++, h, heap[h+0], - name,l); - else - fprintf(stderr, "gdb %d: heap[%d]=%d %d at %s:%d\n",counter++, h, heap[h+0],heap[h+1], - name,l); - return h; -} - - /* end */
--- a/mc-parse.h Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-parse.h Mon Oct 01 01:01:47 2007 +0900 @@ -127,7 +127,6 @@ extern int dlist2(int e1, double d1); #endif extern void error(int n); - extern int glist2(int e1,int e2); extern int glist3(int e1,int e2,int e3); extern int glist4(int e1,int e2,int e3,int e4);
--- a/mc-tree.c Sun Jul 29 23:09:38 2007 +0900 +++ b/mc-tree.c Mon Oct 01 01:01:47 2007 +0900 @@ -649,13 +649,19 @@ return; } if (stmode==STATIC) { - fprintf(vout,"static ",nptr->nm); + fprintf(vout,"static "); } else if (stmode==EXTRN||stmode==EXTRN1) { - fprintf(vout,"extern ",nptr->nm); + fprintf(vout,"extern "); } type_print(n->ty,n,vout); - if (ctmode) { - fprintf(vout,"const ",nptr->nm); + if (ctmode & KONST_BIT) { + fprintf(vout,"const "); + } + if (ctmode & VOLATILE_BIT) { + fprintf(vout,"volatile "); + } + if (ctmode & RESTRICT_BIT) { + fprintf(vout,"restrict "); } fprintf(vout,"%s; ",nptr->nm); }
--- a/mc.h Sun Jul 29 23:09:38 2007 +0900 +++ b/mc.h Mon Oct 01 01:01:47 2007 +0900 @@ -262,49 +262,50 @@ #define BPREINC 49 #define BPOSTINC 50 #define CAST 51 -#define CONV 52 +#define DECL_DATA 52 +#define CONV 53 #define UNARY_ARGS(i) (ADDRESS<=(i%SOP)&&(i%SOP)<=CONV) /* binary argments */ -#define MUL 53 -#define UMUL 54 -#define DIV 55 -#define UDIV 56 -#define MOD 57 -#define UMOD 58 -#define ADD 59 -#define SUB 60 -#define CMP 61 -#define RSHIFT 62 -#define URSHIFT 63 -#define LSHIFT 64 -#define ULSHIFT 65 -#define GT 66 -#define UGT 67 -#define GE 68 -#define UGE 69 -#define LT 70 -#define ULT 71 -#define LE 72 -#define ULE 73 -#define EQ 74 -#define NEQ 75 -#define BAND 76 -#define EOR 77 -#define BOR 78 -#define LAND 79 -#define LOR 80 -#define ASS 81 -#define UCMP 82 -#define UCMPGE 83 -#define CMPGE 84 -#define CMPEQ 85 -#define CMPNEQ 86 -#define ASSOP 87 -#define UASSOP 88 -#define COMMA 89 +#define MUL 54 +#define UMUL 55 +#define DIV 56 +#define UDIV 57 +#define MOD 58 +#define UMOD 59 +#define ADD 60 +#define SUB 61 +#define CMP 62 +#define RSHIFT 63 +#define URSHIFT 64 +#define LSHIFT 65 +#define ULSHIFT 66 +#define GT 67 +#define UGT 68 +#define GE 69 +#define UGE 70 +#define LT 71 +#define ULT 72 +#define LE 73 +#define ULE 74 +#define EQ 75 +#define NEQ 76 +#define BAND 77 +#define EOR 78 +#define BOR 79 +#define LAND 80 +#define LOR 81 +#define ASS 82 +#define UCMP 83 +#define UCMPGE 84 +#define CMPGE 85 +#define CMPEQ 86 +#define CMPNEQ 87 +#define ASSOP 88 +#define UASSOP 89 +#define COMMA 90 #define CASS (COP+ASS) #define CASSOP (COP+ASSOP) @@ -364,21 +365,24 @@ #define LEOR (LOP+EOR) #define LBOR (LOP+BOR) -#define BASS 90 -#define BASSOP 91 -#define BFD_REPL 92 +#define BASS 91 +#define BASSOP 92 +#define BFD_REPL 93 -#define JUMP 93 +#define JUMP 94 +#define DECL_DATA_ARRAY 95 +#define DECL_DATA_LIST 96 +#define DECL_DATA_FIELD 97 -#define STASS 94 +#define STASS 98 #define BINARY_ARGS(i) ((MUL<=(i%SOP)&&(i%SOP)<=STASS)||i==ARRAY) /* ternary argments */ -#define COND 95 -#define UCOND 96 +#define COND 99 +#define UCOND 100 #define SCOND (SOP+COND) #define SUCOND (SOP+UCOND) #define DCOND (DOP+COND) @@ -390,33 +394,33 @@ /* not appeared as tags */ -#define LPAR 97 -#define RPAR 98 -#define LBRA 99 -#define RBRA 100 -#define LC 101 -#define RC 102 -#define COLON 103 -#define SM 104 -#define CNAME 105 +#define LPAR 101 +#define RPAR 102 +#define LBRA 103 +#define RBRA 104 +#define LC 105 +#define RC 106 +#define COLON 107 +#define SM 108 +#define CNAME 109 -#define I2C 106 -#define I2S 107 -#define I2I 108 -#define I2U 109 -#define I2D 110 -#define I2F 111 -#define I2LL 112 -#define I2ULL 113 +#define I2C 110 +#define I2S 111 +#define I2I 112 +#define I2U 113 +#define I2D 114 +#define I2F 115 +#define I2LL 116 +#define I2ULL 117 -#define U2UC 114 -#define U2US 115 -#define U2I 116 -#define U2U 117 -#define U2D 118 -#define U2F 119 -#define U2LL 120 -#define U2ULL 121 +#define U2UC 118 +#define U2US 119 +#define U2I 120 +#define U2U 121 +#define U2D 122 +#define U2F 123 +#define U2LL 124 +#define U2ULL 125 #define D2I (DOP+I2I) @@ -451,27 +455,27 @@ /* statement start */ -#define ST_DECL 122 -#define ST_IF 123 -#define ST_DO 124 -#define ST_WHILE 125 -#define ST_FOR 126 -#define ST_SWITCH 127 -#define ST_COMP 128 -#define ST_BREAK 129 -#define ST_CONTINUE 130 -#define ST_CASE 131 -#define ST_DEFAULT 132 -#define ST_RETURN 133 -#define ST_GOTO 134 -#define ST_ASM 135 -#define ST_LABEL 136 -#define ST_OP 137 -#define ST_COMMENT 138 +#define ST_DECL 126 +#define ST_IF 127 +#define ST_DO 128 +#define ST_WHILE 129 +#define ST_FOR 130 +#define ST_SWITCH 131 +#define ST_COMP 132 +#define ST_BREAK 133 +#define ST_CONTINUE 134 +#define ST_CASE 135 +#define ST_DEFAULT 136 +#define ST_RETURN 137 +#define ST_GOTO 138 +#define ST_ASM 139 +#define ST_LABEL 140 +#define ST_OP 141 +#define ST_COMMENT 142 #define IS_STATEMENT(i) (i==INLINE||(ST_DECL<=i&&i<=ST_COMMENT)) -#define HAS_ADDRESS 139 +#define HAS_ADDRESS 143 /* statement end */ @@ -514,7 +518,8 @@ #define UFERR 35 #define ENERR 36 #define RETERR 37 -#define SIERR 38 +#define UFLDERR 38 +#define SIERR 39 /* error number end */