shithub: scc

Download patch

ref: e4c9da7e693f8c2ad9008ad2c895654d563905fe
parent: f7fddfcd7659f0545c8b3eb367f11f3f68dab7c0
parent: 4f8c064dd03b39ff214733ab69fb49662e75a8dd
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Aug 18 05:56:40 EDT 2015

Merge branch 'master' of ssh://suckless.org/gitrepos/scc

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -82,6 +82,9 @@
 struct caselist {
 	short nr;
 	Symbol *deflabel;
+	Symbol *ltable;
+	Symbol *lbreak;
+	Node *expr;
 	struct scase *head;
 };
 
@@ -282,6 +285,7 @@
 	ORET,
 	ODECL,
 	OSWITCH,
+	OSWITCHT,
 	OAND,
 	OOR,
 	OEQ,
--- a/cc1/code.c
+++ b/cc1/code.c
@@ -7,7 +7,7 @@
 #include "../inc/cc.h"
 #include "cc1.h"
 
-static void emitbin(unsigned, void *),
+static void emitbin(unsigned, void *), emitswitcht(unsigned, void *),
             emitcast(unsigned, void *), emitswitch(unsigned, void *),
             emitsym(unsigned, void *),
             emitexp(unsigned, void *),
@@ -55,7 +55,7 @@
 	[OCOMMA] = ",",
 	[OLABEL] = "L%d\n",
 	[ODEFAULT] = "\tf\tL%d\n",
-	[OCASE] = "\tw\tL%d",
+	[OCASE] = "\tv\tL%d",
 	[OJUMP] = "\tj\tL%d\n",
 	[OBRANCH] = "\tj\tL%d",
 	[OEFUN] = "}",
@@ -121,6 +121,7 @@
 	[ORET] = emitret,
 	[ODECL] = emitdcl,
 	[OSWITCH] = emitswitch,
+	[OSWITCHT] = emitswitcht,
 	[OPAR] = emitbin,
 	[OCALL] = emitbin
 };
@@ -368,7 +369,25 @@
 {
 	Caselist *lcase = arg;
 
-	printf("\teI\t#%0x", lcase->nr);
+	printf("\ts\tL%u", lcase->ltable->id);
+	emitexp(OEXPR, lcase->expr);
+}
+
+static void
+emitswitcht(unsigned op, void *arg)
+{
+	Caselist *lcase = arg;
+	struct scase *p, *next;
+
+	printf("\tt\t#%0x\n", lcase->nr);
+	for (p = lcase->head; p; p = next) {
+		emitsymid(OCASE, p->label);
+		emitexp(OEXPR, p->expr);
+		next = p->next;
+		free(p);
+	}
+	if (lcase->deflabel)
+		emitsymid(ODEFAULT, lcase->deflabel);
 }
 
 Node *
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -301,7 +301,8 @@
 				break;
 			case LONG:
 				if (size == LONG) {
-					size = LLONG;
+					yylval.token = LLONG;
+					size = 0;
 					break;
 				}
 			case SHORT:
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -189,14 +189,13 @@
 Switch(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	Caselist lcase = {.nr = 0, .head = NULL, .deflabel = NULL};
-	struct scase *p, *next;
 	Node *cond;
-	Symbol *lcond;
-	void free(void *ptr);
 
 	expect(SWITCH);
 	expect ('(');
-	cond = expr();
+	cond = eval(expr());
+	/* TODO: why can I not call directly to convert here? */
+
 	switch (BTYPE(cond)) {
 	case INT:
 	case ENUM:
@@ -207,22 +206,16 @@
 	}
 	expect (')');
 
-	lbreak = newsym(NS_LABEL);
-	lcond = newsym(NS_LABEL);
-	emit(OJUMP, lcond);
-	stmt(lbreak, lcont, &lcase);
-	emit(OLABEL, lcond);
+	lcase.expr = cond;
+	lcase.lbreak = newsym(NS_LABEL);
+	lcase.ltable = newsym(NS_LABEL);
+
 	emit(OSWITCH, &lcase);
-	emit(OEXPR, cond);
-	for (p = lcase.head; p; p = next) {
-		emit(OCASE, p->label);
-		emit(OEXPR, p->expr);
-		next = p->next;
-		free(p);
-	}
-	if (lcase.deflabel)
-		emit(ODEFAULT, lcase.deflabel);
-	emit(OLABEL, lbreak);
+	stmt(lbreak, lcont, &lcase);
+	emit(OJUMP, lcase.lbreak);
+	emit(OLABEL, lcase.ltable);
+	emit(OSWITCHT, &lcase);
+	emit(OLABEL, lcase.lbreak);
 }
 
 static void
@@ -243,6 +236,7 @@
 	emit(OLABEL, pcase->label = newsym(NS_LABEL));
 	lswitch->head = pcase;
 	++lswitch->nr;
+	stmt(lbreak, lcont, lswitch);
 }
 
 static void
@@ -254,6 +248,8 @@
 	expect(':');
 	emit(OLABEL, ldefault);
 	lswitch->deflabel = ldefault;
+	++lswitch->nr;
+	stmt(lbreak, lcont, lswitch);
 }
 
 static void
--- a/cc1/tests/chktest.sh
+++ b/cc1/tests/chktest.sh
@@ -23,7 +23,7 @@
 	/^output:$/ {
 		copyon=1
 	}
-	/^\*/  {
+	/^\*\//  {
 		copyon=0
 	}
 	copyon==1 && !/^output:$/  {
--- /dev/null
+++ b/cc1/tests/test012.c
@@ -1,0 +1,111 @@
+/*
+name: TEST012
+description: Basic switch test
+output:
+F1
+G1	F1	main
+{
+-
+A2	I	x
+	A2	#I0	:I
+	s	L4	A2
+L5
+	j	L3
+L4
+	t	#1
+	v	L5	#I0
+L3
+	s	L7	A2
+L8
+	s	L10	A2
+L11
+	j	L12
+L13
+	yI	#I1
+	j	L9
+L10
+	t	#2
+	v	L11	#I0
+	f	L13
+L9
+	j	L6
+L7
+	t	#1
+	v	L8	#I0
+L6
+	yI	#I2
+L12
+	s	L15	A2
+L16
+	yI	#I3
+	j	L14
+L15
+	t	#1
+	v	L16	#I1
+L14
+	s	L18	A2
+	A2	#I2	:I
+L19
+L20
+	yI	#I4
+	j	L17
+L18
+	t	#1
+	v	L20	#I1
+L17
+	s	L22	A2
+L23
+	yI	A2
+L24
+	yI	#I1
+L25
+	yI	#I1
+	j	L21
+L22
+	t	#3
+	v	L24	#I1
+	v	L23	#I0
+	f	L25
+L21
+}
+*/
+
+
+
+int
+main()
+{
+	int x;
+
+	x = 0;
+	switch(x)
+	case 0:
+		;
+	switch(x)
+	case 0:
+		switch(x) {
+		case 0:
+			goto next;
+		default:
+			return 1;
+		}
+	return 2;
+	next:
+	switch(x)
+	case 1:
+		return 3;
+	switch(x) {
+		x = 1 + 1;
+		foo:
+	case 1:
+		return 4;
+	}
+	switch(x) {
+	case 0:
+		return x;
+	case 1:
+		return 1;
+	default:
+		return 1;
+	}
+}
--- a/cc1/types.c
+++ b/cc1/types.c
@@ -222,7 +222,6 @@
 			goto invalid_type;
 		return booltype;
 	case 0:
-		warn("type defaults to 'int' in declaration");
 		/* fallthrough */
 	case INT:
 		switch (size) {