shithub: scc

Download patch

ref: 671acae249562120edaec2fb6ff24411ef9be84c
parent: 38c240c4f09858a4ce71d70ee7fe16e7df7c9bff
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Jan 17 15:47:02 EST 2016

Add initializer struct

This struct is needed for the designated initializers,
because we have to process the full designation before
of emitting something.

--- a/cc1/init.c
+++ b/cc1/init.c
@@ -11,6 +11,12 @@
 	struct designator *next;
 };
 
+struct inititlizer {
+	Node *expr;
+	struct designator *dp;
+	struct inititalizer *next;
+};
+
 static TINT
 arydesig(Type *tp)
 {
@@ -56,7 +62,7 @@
 static struct designator *
 designation(Type *tp)
 {
-	struct designator *des = NULL, *d;
+	struct designator *dp, *d, *head;
 	TINT (*fun)(Type *);
 
 	for (;;) {
@@ -64,37 +70,38 @@
 		case '[': fun = arydesig;   break;
 		case '.': fun = fielddesig; break;
 		default:
-			if (des)
+			if (head)
 				expect('=');
-			return des;
+			return head;
 		}
 		d = xmalloc(sizeof(*d));
 		d->next = NULL;
 
-		if (!des) {
-			des = d;
+		if (!head) {
+			head = dp = d;
 		} else {
-			des->next = d;
-			des = d;
+			dp->next = d;
+			dp = d;
 		}
-		des->pos  = (*fun)(tp);
+		dp->pos  = (*fun)(tp);
 	}
 }
 
-static void
+static struct designator *
 initlist(Symbol *sym, Type *tp)
 {
-	struct designator *des;
+	struct designator *dp;
+	struct inititlizer *ip;
 	int toomany = 0;
 	TINT n;
 	Type *newtp;
 
 	for (n = 0; ; ++n) {
-		if ((des = designation(tp)) == NULL) {
-			des = xmalloc(sizeof(*des));
-			des->pos = n;
+		if ((dp = designation(tp)) == NULL) {
+			dp = xmalloc(sizeof(*dp));
+			dp->pos = n;
 		} else {
-			n = des->pos;
+			n = dp->pos;
 		}
 		switch (tp->op) {
 		case ARY:
@@ -128,7 +135,10 @@
 			}
 			break;
 		}
-		initializer(sym, newtp, n);
+		if (accept('{'))
+			return initlist(sym, tp);
+		ip->expr = assign(NULL);
+
 		if (!accept(','))
 			break;
 	}
@@ -138,10 +148,9 @@
 		tp->n.elem = n + 1;
 		tp->defined = 1;
 	}
+	return dp;
 }
 
-extern Node *assign(Node *np);
-
 void
 initializer(Symbol *sym, Type *tp, int nelem)
 {
@@ -153,19 +162,12 @@
 
 	switch (yytoken) {
 	case '{':
-		initlist(sym, tp); /* FIXME: This code is not complete */
+		initlist(sym, tp);
 		return;
 	case '=':
 		np = assign(varnode(sym));
 		break;
 	}
-
-	/* FIXME: old code used in the recursive call
-	 * if (!sym)
-	 *	return;
-	 * if (nelem >= 0)
-	 *	return;
-	 */
 
 	if (flags & ISDEFINED) {
 		errorp("redeclaration of '%s'", sym->name);