shithub: scc

Download patch

ref: 45c7260ce0fb41d8bf7eb57274af599e84904b06
parent: 328f45d5dcadced32eaeee1ea0a6f05f7cb2a969
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Apr 15 17:59:52 EDT 2014

Add integer conversions

When two integer types with different size are together in an
expression then there are some rules that indicate what is the
size of both operands.

--- a/cc.h
+++ b/cc.h
@@ -44,13 +44,14 @@
 struct ctype {
 	uint8_t op;           /* type builder operator */
 	char letter;          /* letter of the type */
-	short nelem;          /* number of elements in arrays */
-	unsigned defined : 1; /* type defined (is not a forward reference) */
-	unsigned sign : 1;    /* sign type */
+	bool defined : 1; /* type defined (is not a forward reference) */
+	bool sign : 1;    /* sign type */
 	struct symbol *sym;   /* symbol of the tag identifier */
 	struct ctype *type;   /* base type */
 	struct ctype *next;   /* next element in the hash */
 	union {
+		signed char size;
+		short nelem;          /* number of elements in arrays */
 		struct funpar *pars;  /* function parameters */
 		struct field *fields; /* aggregate fields */
 	} u;
--- a/expr.c
+++ b/expr.c
@@ -38,8 +38,30 @@
 }
 
 static void
-intconv(Node **np1, Node **np2)
+intconv(Node **p1, Node **p2)
 {
+	Type *tp1, *tp2, *new1, *new2;
+	Node *np1 = *p1, *np2 = *p2;
+	signed char n;
+
+	tp1 = UNQUAL(np1->type);
+	tp2 = UNQUAL(np2->type);
+	new1 = new2 = NULL;
+	n = tp1->u.size - tp2->u.size;
+
+	if (n > 0)
+		new2 = tp1;
+	else if (n < 0)
+		new1 = tp2;
+	else if (tp1->sign)
+		new2 = tp1;
+	else
+		new1 = tp2;
+
+	if (new1)
+		*p1 = castcode(np1, new1);
+	else
+		*p2 = castcode(np2, new2);
 }
 
 static void
@@ -60,7 +82,8 @@
 
 	if (t1 != INT || t2 != INT)
 		error("No integer operand in bit logical operation");
-	intconv(&np1, &np2);
+	if (tp1 != tp2)
+		intconv(&np1, &np2);
 	return bincode(op, np1->type, np1, np2);
 }
 
@@ -125,6 +148,7 @@
 		case INT:
 			if (tp1 != tp2)
 				intconv(&np1, &np2);
+			tp1 = np1->type;
 			break;
 		case FLOAT:
 			np2 = castcode(np1, np2->type);
@@ -142,6 +166,7 @@
 		case FLOAT:
 			if (tp1 != tp2)
 				floatconv(&np1, &np2);
+			tp1 = np1->type;
 			break;
 		case INT:
 			np2 = castcode(np2, np1->type);
--- a/types.c
+++ b/types.c
@@ -16,61 +16,72 @@
 	*booltype = &(Type) {
 		.op = INT,
 		.letter = 'B',
-		.defined = 1
+		.defined = 1,
+		.u.size = 0
 	},
 	*uchartype = &(Type) {
 		.op = INT,
 		.letter = 'M',
 		.sign = 1,
-		.defined = 1
+		.defined = 1,
+		.u.size = 1
 	},
 	*chartype = &(Type) {
 		.op = INT,
 		.letter = 'C',
-		.defined = 1
+		.defined = 1,
+		.u.size = 1
 	},
+	*ushortype = &(Type) {
+		.op = INT,
+		.letter = 'E',
+		.defined = 1,
+		.u.size = 2
+	},
+	*shortype = &(Type) {
+		.op = INT,
+		.letter = 'K',
+		.defined = 1,
+		.u.size = 2
+	},
 	*uinttype = &(Type) {
 		.op = INT,
 		.letter = 'U',
 		.sign = 1,
-		.defined = 1
+		.defined = 1,
+		.u.size = 3
 	},
 	*inttype = &(Type) {
 		.op = INT,
 		.letter = 'I',
-		.defined = 1
+		.defined = 1,
+		.u.size = 3
 	},
-	*ushortype = &(Type) {
-		.op = INT,
-		.letter = 'E',
-		.defined = 1
-	},
-	*shortype = &(Type) {
-		.op = INT,
-		.letter = 'K',
-		.defined = 1
-	},
 	*longtype = &(Type) {
 		.op = INT,
 		.letter = 'L',
-		.defined = 1
+		.defined = 1,
+		.u.size = 4
 	},
 	*ulongtype = &(Type) {
 		.op = INT,
 		.letter = 'Z',
 		.sign = 1,
-		.defined = 1
+		.defined = 1,
+		.u.size = 4
 	},
 	*ullongtype = &(Type) {
 		.op = INT,
 		.letter = 'O',
 		.sign = 1,
-		.defined = 1
+		.defined = 1,
+		.u.size = 5
 	},
 	*llongtype = &(Type) {
 		.op = INT,
 		.letter = 'G',
-		.defined = 1
+		.defined = 1,
+		.u.size = 5
 	},
 	*floattype = &(Type) {
 		.op = FLOAT,
@@ -131,7 +142,7 @@
 	if (op != FTN || op != STRUCT || op != UNION || op != ENUM) {
 		for (bp = *tbl; bp; bp = bp->next) {
 			if (bp->type == tp && bp->op == op &&
-			    bp->sym == sym && bp->nelem == nelem) {
+			    bp->sym == sym && bp->u.nelem == nelem) {
 				return bp;
 			}
 		}
@@ -149,7 +160,7 @@
 	bp->next = *tbl;
 	bp->type = tp;
 	bp->op = op;
-	bp->nelem = nelem;
+	bp->u.nelem = nelem;
 	bp->sym = sym;
 	bp->letter = letter;
 	return *tbl = bp;