changeset 309:a86612cf1a19

struct partial initialization (local struct copy)
author kono
date Thu, 10 Jun 2004 19:09:36 +0900
parents e1d17d6adfcc
children 5ae5857ded2c
files .gdbinit Changes mc-code-ia32.c mc-code-mips.c mc-parse.c mc.h
diffstat 6 files changed, 101 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Thu Jun 10 16:24:15 2004 +0900
+++ b/.gdbinit	Thu Jun 10 19:09:36 2004 +0900
@@ -1,7 +1,7 @@
 tb main
 # run  -s test/arg.c
 # run  -s -ob00.s mc-parse.c
-run  -s -ob02.s mc-code-powerpc.c
+run  -s test/strinit.c
 # run -s test/code-gen-all.c
 define regs 
 printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4
--- a/Changes	Thu Jun 10 16:24:15 2004 +0900
+++ b/Changes	Thu Jun 10 19:09:36 2004 +0900
@@ -4861,3 +4861,9 @@
 	struct partial field init
         hoge##name
 がないね。というか、これだけ? (頑張れ〜)
+
+Thu Jun 10 17:57:35 JST 2004
+
+struct partial field init は、できたんだけど、局所変数の場合
+は、不定の部分を0にしているみたいね。つまり、static にとって、
+コピーしているみたいね。これは標準的なセマンティクスなのかな?
--- a/mc-code-ia32.c	Thu Jun 10 16:24:15 2004 +0900
+++ b/mc-code-ia32.c	Thu Jun 10 19:09:36 2004 +0900
@@ -1875,6 +1875,11 @@
     } else {
 	data_mode(0);
     }
+    if (t==EMPTY) {
+        if(car(e)!=CONST) error(-1);
+        printf("\t.space\t%d\n",cadr(e));
+        return;
+    }
     if(car(e)==CONST) {       
 	if (t==CHAR||t==UCHAR) {
 	    printf("\t.byte %d\n",cadr(e));
--- a/mc-code-mips.c	Thu Jun 10 16:24:15 2004 +0900
+++ b/mc-code-mips.c	Thu Jun 10 19:09:36 2004 +0900
@@ -3237,6 +3237,11 @@
     } else {
 	data_mode(0);
     }
+    if (t==EMPTY) {
+        if(car(e)!=CONST) error(-1);
+        printf("\t.space\t%d\n",cadr(e));
+        return;
+    }
     if(car(e)==CONST) {       
 	if (t==CHAR||t==UCHAR) {
 	    printf("\t.byte %d\n",cadr(e));
--- a/mc-parse.c	Thu Jun 10 16:24:15 2004 +0900
+++ b/mc-parse.c	Thu Jun 10 19:09:36 2004 +0900
@@ -940,6 +940,23 @@
     }
 }
 
+char *
+new_static_name(char *name)
+{
+    int ndsp;
+    char *p = cheapp;
+
+    while((*cheapp++ = *name++));
+    ndsp = ++stat_no;
+    cheapp[-1] = '.';
+    while(ndsp>0) {
+	*cheapp++ = ndsp%10+'0';
+	ndsp /= 10;
+    }
+    *cheapp++ = 0;
+    return p;
+}
+
 static NMTBL *
 def(NMTBL *n)
 {
@@ -991,14 +1008,7 @@
 	    nsc = STATIC;
 	n->sc = nsc;
 	if (stmode==LDECL) {
-	    copy(n,n->nm);
-	    cheapp[-1] = '.';
-	    ndsp = ++stat_no;
-	    while(ndsp>0) {
-		*cheapp++ = ndsp%10+'0';
-		ndsp /= 10;
-	    }
-	    *cheapp++ = 0;
+	    n->nm = new_static_name(n->nm);
 	}
 	if(sym==ASS) {
 	    if (n->dsp==-1) error(-1);  // already initialized
@@ -1105,10 +1115,11 @@
     }
 }
 
-static void
+static int
 str_init_eq()
 {
     // error(-1);  // duplicate struct field value
+    return 2;      // allow override keep unique
 }
 
 static int decl_str_init;
@@ -1120,27 +1131,30 @@
 
     if(mode==GDECL) {
  	emit_data(e,t,n);
-	return offset+size(t);
     } else if(mode==STADECL) {
  	emit_data(e,t,n);
-	return offset+size(t);
     } else if(mode==LDECL) {
+	if (t==EMPTY) return offset+cadr(e);
 	ass = assign_expr0(
     (n->sc==REGISTER||n->sc==DREGISTER||n->sc==FREGISTER||n->sc==LREGISTER)?
 	    list3(n->sc,n->dsp,(int)n):
 	    list2(LVAR,n->dsp+offset),
-	e,t,type);
+	e,t,t);
 	init_vars = list2(ass,init_vars);
-	return offset+size(t);
     } else if(mode==SFDINIT) {
-	insert_ascend(decl_str_init,list4(offset,0,e,t),str_init_eq);
-	return offset+size(t);
+	decl_str_init=insert_ascend(decl_str_init,
+		list4(offset,0,e,t),str_init_eq);
     } else {
 	error(DCERR);
+	return offset;
     }
-    return 0; /* not reached */
+    return offset+((t==EMPTY)?cadr(e):size(t));
 }
 
+#define LOCAL_STRUCT_INIT_STATIC 1
+
+static NMTBL local_struct;
+
 static void
 decl_data_field(int type,NMTBL *n,int offset)
 {
@@ -1155,25 +1169,40 @@
 	error(DCERR);
 	return;
     }
+    if (mode==LDECL && LOCAL_STRUCT_INIT_STATIC) {
+	local_struct.nm  = new_static_name("_lstrcut");
+	local_struct.sc = STATIC;
+	mode=STADECL;
+	decl_data_field(type,&local_struct,offset);
+	e = size(type);
+	init_vars = list2(
+	    list4(STASS,list2(LVAR,n->dsp+offset),
+		list3(RSTRUCT,list2(GVAR,(int)&local_struct),e),e),
+	    init_vars);
+	return;
+    }
     mode=SFDINIT;
     t1 = caddr(type);  /* list of fields */
-    while(t1) {
+    while(1) {
 	if (skipspc()=='.') { /* struct/union field initializaer */
+	    getsym(0); // skip period
 	    getsym(0);
 	    if (sym==IDENT) {
-		type = search_struct_type(type,nptr->nm,&foffset);
+		t1 = search_struct_type(type,nptr->nm,&foffset);
+		getsym(0);
 		if (sym==ASS) {
-		    decl_data(type,n,foffset);
-		    continue;
-		} 
-	    }
-	    error(TYERR); /* should be initialization error */
-	    continue;
+		    decl_data(t1,n,foffset);
+		} else
+		    error(TYERR); /* should be initialization error */
+	    } else
+		error(TYERR); /* should be initialization error */
+	} else {
+	    if(!t1) error(-1);
+	    offset = decl_data(car(t1),n,offset);  /* alignment? */
+	    t1 = cadr(t1);
 	}
-	offset = decl_data(car(t1),n,offset);  /* alignment? */
-	t1 = cadr(t1);
 	if ( t1 && sym==COMMA) { conv->comma_(); continue; }
-	if (!t1 && sym==COMMA) getsym(0); /* extra comma */
+	// if (!t1 && sym==COMMA) getsym(0); /* extra comma */
 	if (sym==RC) break; // premature end
     }
     mode = mode_save;
@@ -1214,13 +1243,13 @@
 	mode = mode_save;
  	if(car(e)!=CONST && t==CHAR)
  	    error(TYERR);
- 	offset = assign_data(e,t,n,offset);
+ 	offset = assign_data(rvalue(e),t,n,offset);
  	type=t;
 	return offset;
     } else if (t==FLOAT||t==DOUBLE||t==LONGLONG||t==ULONGLONG) {
  	e=expr1();
 	mode = mode_save;
- 	offset = assign_data(e,t,n,offset);
+ 	offset = assign_data(rvalue(e),t,n,offset);
  	type=t;
 	return offset;
     } else if ((t1 = car(t)) && t1==ARRAY) {
@@ -1973,10 +2002,11 @@
     cslist = slist;
 }
 
-static void
+static int
 docase_eq()
 {
     error(-1);  // duplicate case value
+    return 0;   // remove duplicate value
 }
 
 static void
@@ -3198,9 +3228,12 @@
 
 /* filed name search */
 
+    /* type = list4(s,disp,fields,tag_nptr); */
+
 static int
 search_struct_type(int t,char *name,int *dsp)
 {
+    t = caddr(t);
     for(;t;t = cadr(t)) {
 	if (neqname((char *)caddr(t),name)==0) {
 	    *dsp = cadddr(t);
@@ -3222,7 +3255,7 @@
 	e=rvalue(e);
     /* type = list4(s,disp,fields,tag_nptr); */
     /* print_fields(caddr(type),"strop"); */
-    type = search_struct_type(caddr(type),nptr->nm,&dsp);
+    type = search_struct_type(type,nptr->nm,&dsp);
     if (!type) { error(TYERR); return INT; }
     if(dsp) {
 	switch(car(e)) {
@@ -5118,19 +5151,33 @@
 }
 
 int
-insert_ascend(int p,int e,void eq())
+insert_ascend(int p,int e,int eq())
 {
-    int p1,p2;
+    int p1,p2,dup;
     if(!p) return e;
-    if (car(p)>car(e)) {
+    if (car(p)==car(e)) {
+	if ((dup=eq())==0)  // duplicate value is not override
+	    return p;
+	else if (dup==2) {  // keep unique allow override
+	    cadr(e) = cadr(p);  // skip one
+	    return e;
+	}                   // any other value allows duplicate
+    } else if (car(p)>car(e)) {
 	cadr(e) = p;
 	return e;
     }
     p1=p;
     while(cadr(p)) {
 	p = cadr(p2=p);
-	if (car(p)==car(e)) eq();
-	if (car(p)>=car(e)) {
+	if (car(p)==car(e)) {
+	    if ((dup=eq())==0)  // duplicate value is not override
+		return p1;
+	    else if (dup==2) {  // keep unique allow override
+		cadr(e) = cadr(p);  // skip one
+		cadr(p2) = e;
+		return p1;
+	    }                   // any other value allows duplicate
+	} else if (car(p)>=car(e)) {
 	    cadr(e) = cadr(p2);
 	    cadr(p2) = e;
 	    return p1;
--- a/mc.h	Thu Jun 10 16:24:15 2004 +0900
+++ b/mc.h	Thu Jun 10 19:09:36 2004 +0900
@@ -481,7 +481,7 @@
 extern int assign_expr0(int e1,int e2,int t,int type) ;
 extern int assign_expr(int e1,int e2,int t,int type) ;
 extern int append4(int p,int a1,int a2,int a3);
-extern int insert_ascend(int p,int e,void eq());
+extern int insert_ascend(int p,int e,int eq());
 
 
 #define car(e) (heap[(int)(e)])