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 */