shithub: scc

Download patch

ref: 951024c4481a3f63bfab9a83364d6861f16ee5d9
parent: d247bc3fa770720335e31b8d3c735200b2484c30
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Mar 11 13:36:05 EDT 2014

Change storage codification

This form of codificate storage makes trivial all the checks in
declarations.

--- a/decl.c
+++ b/decl.c
@@ -172,9 +172,9 @@
 	expect('}');
 }
 
-bool
+static bool
 specifier(register struct ctype *tp,
-          struct storage *store, struct qualifier *qlf)
+          char *store, struct qualifier *qlf)
 {
 	unsigned char tok;
 
@@ -184,7 +184,10 @@
 			qlf = qualifier(qlf, yyval->c);
 			break;
 		case STORAGE:
-			store = storage(store, yyval->c);
+			if (*store)
+				error("two or more storage specifier");
+			/* TODO: check bad storage in file-scope */
+			*store |= yyval->c;
 			break;
 		case TYPE:
 			tp = ctype(tp, tok = yyval->c);
@@ -196,7 +199,7 @@
 				else
 					structdcl(tp);
 				return true;
-			case TYPEDEF:
+			case TYPENAME:
 				tp->base = &yyval->ctype;
 				break;
 			}
@@ -208,7 +211,7 @@
 
 check_type:
 	if (!tp->defined) {
-		if (!store->defined &&
+		if (*store &&
 		    !qlf->defined &&
 		    curctx != CTX_OUTER &&
 		    nested_tags == 0) {
@@ -285,7 +288,7 @@
 
 static struct node *
 listdcl(struct ctype *base,
-        struct storage *store,
+        char store,
 	struct qualifier *qlf,
 	unsigned char ns, unsigned char isfun)
 {
@@ -300,12 +303,12 @@
 		register struct symbol *sym;
 
 		sym = declarator(base, ns, isfun);
-		sym->store = *store;
+		sym->store = store;
 		sym->qlf = *qlf;
 		sym->ctype = *decl_type(base);
-		if (sym->store.c_typedef) {
+		if (sym->store) {
 			sym->tok = TYPE;
-			sym->c = TYPEDEF;
+			sym->c = TYPENAME;
 		}
 		tp = &sym->ctype;
 		aux = NULL;
@@ -362,17 +365,16 @@
 decl(unsigned char ns)
 {
 	struct ctype base;
-	struct storage store;
+	char store = 0;
 	struct qualifier qlf;
 
 	initctype(&base);
-	initstore(&store);
 	initqlf(&qlf);
 
 	if (!specifier(&base, &store, &qlf))
 		return NULL;
 
-	if (store.defined && ns != NS_IDEN)
+	if (store && ns != NS_IDEN)
 		error("storage specifier in a struct/union field declaration");
 
 	switch (base.type) {
@@ -380,7 +382,7 @@
 		if (yytoken == ';')
 			return NULL;
 	default:
-		return listdcl(&base, &store, &qlf, ns, 0);
+		return listdcl(&base, store, &qlf, ns, 0);
 	}
 }
 
@@ -387,11 +389,10 @@
 void
 type_name(struct ctype *tp)
 {
-	struct storage store;
 	struct qualifier qlf;
+	char store = 0;
 
 	initctype(tp);
-	initstore(&store);
 	initqlf(&qlf);
 
 	if (!specifier(tp, &store, &qlf))
--- a/expr.c
+++ b/expr.c
@@ -129,19 +129,18 @@
 static struct node *
 cast(void)
 {
-	register struct node *np;
 	struct ctype type;
 
-	while (accept('(')) {
-		switch (yytoken) {
+repeat:	if (yytoken == '(') {
+		switch (ahead()) {
 		case STORAGE: case TQUALIFIER: case TYPE:
+			next();
 			type_name(&type); /* TODO: type_name should return a np*/
-			break;
+			expect(')');
+			goto repeat;
 		default:
-			np = expr();
 			break;
 		}
-		expect(')');
 	}
 	return unary();
 }
--- a/symbol.h
+++ b/symbol.h
@@ -23,15 +23,6 @@
 	bool defined: 1;
 };
 
-struct storage {
-	bool c_typedef : 1;
-	bool c_extern : 1;
-	bool c_static : 1;
-	bool c_auto : 1;
-	bool c_register : 1;
-	bool defined: 1;
-};
-
 struct ctype {
 	unsigned type : 5;
 	bool c_const : 1;
@@ -53,7 +44,7 @@
 
 struct symbol {
 	struct ctype ctype;
-	struct storage store;
+	char store;
 	struct qualifier qlf;
 	unsigned char ctx;
 	unsigned char ns;
@@ -82,12 +73,10 @@
 extern void freesyms(void);
 extern struct symbol *lookup(const char *s, signed char ns);
 extern void insert(struct symbol *sym, unsigned char ctx);
-extern struct storage *storage(struct storage *tp, unsigned char mod);
 extern struct qualifier *qualifier(register struct qualifier *, unsigned char);
 extern void delctype(struct ctype *tp);
 extern unsigned char hash(register const char *s);
 extern struct ctype *initctype(register struct ctype *tp);
-extern struct storage *initstore(register struct storage *store);
 extern struct qualifier * initqlf(struct qualifier *qlf);
 
 #ifndef NDEBUG
--- a/tokens.h
+++ b/tokens.h
@@ -11,13 +11,13 @@
 	/* types */
 	INT = 1, CHAR, FLOAT, LONG, LLONG, SHORT, VOID, DOUBLE,
 	LDOUBLE, STRUCT, UNION, ENUM, BOOL, ARY, PTR, FTN,
-	COMPLEX, IMAGINARY, BITFLD, TYPE,
-	/* storage specifier */
-	TYPEDEF, EXTERN, STATIC, AUTO, REGISTER, STORAGE,
+	COMPLEX, IMAGINARY, BITFLD, TYPENAME, TYPE,
 	/* type qualifier */
 	VOLATILE, CONST, RESTRICT, TQUALIFIER,
 	/* sign specifier */
 	UNSIGNED, SIGNED,
+	/* storage specifier */
+	STORAGE,
 	/* other tokens */
 	IDEN = 128, CONSTANT, SIZEOF,
 	INDIR, INC, DEC, SHL, SHR,
@@ -29,6 +29,12 @@
 	CONTINUE, BREAK, RETURN, EOFTOK, NOTOK
 };
 
+#define TYPEDEF  (1<<0)
+#define EXTERN   (1<<1)
+#define STATIC   (1<<2)
+#define AUTO     (1<<3)
+#define REGISTER (1<<4)
+#define STORAGE  (1<<5)
 
 struct symbol;
 extern struct symbol *yyval;
--- a/types.c
+++ b/types.c
@@ -28,17 +28,6 @@
 	return tp;
 }
 
-struct storage *
-initstore(register struct storage *store)
-{
-	extern unsigned char curctx;
-	memset(store, 0, sizeof(*store));
-
-	if (curctx != CTX_OUTER)
-		store->c_auto = 1;
-	return store;
-}
-
 void
 delctype(register struct ctype *tp)
 {
@@ -188,7 +177,7 @@
 			goto invalid_sign;
 		}
 		break;
-	case TYPEDEF:
+	case TYPENAME:
 		assert(!type);
 		if (tp->c_signed || tp->c_unsigned)
 			goto invalid_sign;
@@ -236,46 +225,6 @@
 	return qlf;
 duplicated:
 	error("duplicated '%s'", yytext);
-}
-
-struct storage *
-storage(register struct storage *sp, unsigned char mod)
-{
-	extern unsigned char curctx;
-
-	if (!sp->defined)
-		sp->c_auto = 0;
-	else
-		error("Two or more storage specifier");
-
-	switch (mod) {
-	case TYPEDEF:
-		sp->c_typedef = 1;
-		break;
-	case EXTERN:
-		sp->c_extern = 1;
-		break;
-	case STATIC:
-		sp->c_static = 1;
-		break;
-	case AUTO:
-		if (curctx == CTX_OUTER)
-			goto bad_file_scope_storage;
-		sp->c_auto = 1;
-		break;
-	case REGISTER:
-		if (curctx == CTX_OUTER)
-			goto bad_file_scope_storage;
-		sp->c_register = 1;
-		break;
-	default:
-		assert(0);
-	}
-	sp->defined = 1;
-	return sp;
-
-bad_file_scope_storage:
-	error("file-scope declaration specifies '%s'", yytext);
 }
 
 #ifndef NDEBUG