shithub: scc

Download patch

ref: 4b3919e775c8f902db77f43db4412e9f6b544a00
parent: c2d71566fa9857e9cb87d0508d9b75f7f5fe2c94
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Dec 9 13:54:29 EST 2016

[cc1] Add basic cupport for bit fields

This is a first implementation of bitfields which adds the parsing
of the expression and checks all the errors that can happen in a
bitfield declaration, but does nothing with the bit field definition,
so they will act like usual integers (which is allowed by the
standard).

--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -609,6 +609,7 @@
 	return sym;
 }
 
+#define NAME(s) (*(s)->name ? (s)->name : "<anonymous>")
 static Symbol *
 field(struct decl *dcl)
 {
@@ -618,8 +619,30 @@
 	TINT n = structp->n.elem;
 	int err = 0;
 
-	if (empty(sym, tp, 0))
+	/* TODO: print name of the field in the errors */
+	if (accept(':')) {
+		Node *np;
+		TINT n;
+
+		if ((np = iconstexpr()) == NULL) {
+			unexpected();
+			n = 0;
+		} else {
+			n = np->sym->u.i;
+			freetree(np);
+		}
+		if (n == 0 && *sym->name)
+			errorp("zero width for bit-field '%s'", sym->name);
+		if (tp != booltype && tp != inttype && tp != uinttype)
+			errorp("bit-field '%s' has invalid type", NAME(sym));
+		if (n < 0)
+			errorp("negative width in bit-field '%s'", NAME(sym));
+		else if (n > tp->size*8)
+			errorp("width of '%s' exceeds its type", NAME(sym));
+	} else if (empty(sym, tp, 0)) {
 		return sym;
+	}
+
 	if (tp->op == FTN) {
 		errorp("invalid type in struct/union");
 		err = 1;
@@ -649,6 +672,7 @@
 
 	return sym;
 }
+#undef NAME
 
 static void
 bad_storage(Type *tp, char *name)