shithub: scc

Download patch

ref: 3a225104759c18a70e8eb918d88a07111f3a128b
parent: f6970279c96254b3407c1d0f2ade3342c26b87b6
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 8 17:35:40 EDT 2015

Add initializers for non static local variables

This is the simpler case, because we only have to generate
an assignation.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -373,6 +373,7 @@
 extern int negop(int op);
 extern bool cmpnode(Node *np, TUINT val);
 extern Node *decay(Node *np);
+extern Node *assignop(char op, Node *lp, Node *rp);
 
 /* cpp.c */
 extern void icpp(void);
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -360,18 +360,28 @@
 
 /* TODO: check correctness of the initializator  */
 /* TODO: emit initializer */
-static struct node *
+static void
 initializer(Symbol *sym)
 {
+	Type *tp = sym->type;
+	Node *np;
+
 	if (accept('{')) {
 		initializer(sym);
 		expect('}');
-	} else {
-		do {
-			expr();
-		} while (accept(','));
+		return;
 	}
-	return NULL;
+	np = expr();
+	if ((np = convert(np, tp, 0)) == NULL)
+		goto bad_initializer;
+	if ((sym->flags & ISLOCAL) == 0) {
+		emit(OEXPR, assignop(OASSIGN, varnode(sym), np));
+		return;
+	}
+	return;
+
+bad_initializer:
+	errorp("invalid initializer");
 }
 
 static Symbol *
@@ -683,13 +693,13 @@
 		sym->flags = flags;
 	}
 
-	if (accept('='))
-		initializer(sym);
 	/* TODO: disallow initializators in functions */
 	/* TODO: check if typedef has initializer */
 	/* TODO: check if the variable is extern and has initializer */
 	if (sym->token == IDEN && sym->type->op != FTN)
 		emit(ODECL, sym);
+	if (accept('='))
+		initializer(sym);
 	return sym;
 
 redeclaration:
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -421,7 +421,7 @@
 	return content(OPTR, np);
 }
 
-static Node *
+Node *
 assignop(char op, Node *lp, Node *rp)
 {
 	int force = 0;