shithub: scc

Download patch

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

Change type qualfier codification

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

--- a/decl.c
+++ b/decl.c
@@ -173,8 +173,7 @@
 }
 
 static bool
-specifier(register struct ctype *tp,
-          char *store, struct qualifier *qlf)
+specifier(register struct ctype *tp, char *store, char *qlf)
 {
 	unsigned char tok;
 
@@ -181,7 +180,11 @@
 	for (;; next()) {
 		switch (yytoken) {
 		case TQUALIFIER:
-			qlf = qualifier(qlf, yyval->c);
+			if (*qlf && !options.repeat)
+				error("duplicated '%s'", yytext);
+			if (yyval->c == RESTRICT)
+				error("invalid use of restrict");
+			*qlf |= yyval->c;
 			break;
 		case STORAGE:
 			if (*store)
@@ -211,8 +214,7 @@
 
 check_type:
 	if (!tp->defined) {
-		if (*store &&
-		    !qlf->defined &&
+		if (*store && *qlf &&
 		    curctx != CTX_OUTER &&
 		    nested_tags == 0) {
 			return false;
@@ -245,16 +247,12 @@
 
 	if (yytoken == '*') {
 		for (bp = qlf; n < NR_DECLARATORS ; ++n) {
-			switch (yytoken) {
-			case '*':
-				yytoken = PTR;
-			case CONST: case VOLATILE: case RESTRICT:
-				*bp++ = yytoken;
-				next();
-				continue;
-			default:
+			if (yytoken == '*')
+				*bp++ = PTR;
+			else if (yytoken == TQUALIFIER)
+				*bp++ = yyval->c;
+			else
 				goto direct;
-			}
 		}
 		error("Too much type declarators");
 	}
@@ -288,8 +286,7 @@
 
 static struct node *
 listdcl(struct ctype *base,
-        char store,
-	struct qualifier *qlf,
+        char store, char qlf,
 	unsigned char ns, unsigned char isfun)
 {
 	struct compound c;
@@ -304,7 +301,7 @@
 
 		sym = declarator(base, ns, isfun);
 		sym->store = store;
-		sym->qlf = *qlf;
+		sym->qlf = qlf;
 		sym->ctype = *decl_type(base);
 		if (sym->store) {
 			sym->tok = TYPE;
@@ -365,11 +362,9 @@
 decl(unsigned char ns)
 {
 	struct ctype base;
-	char store = 0;
-	struct qualifier qlf;
+	char store = 0, qlf = 0;
 
 	initctype(&base);
-	initqlf(&qlf);
 
 	if (!specifier(&base, &store, &qlf))
 		return NULL;
@@ -382,7 +377,7 @@
 		if (yytoken == ';')
 			return NULL;
 	default:
-		return listdcl(&base, store, &qlf, ns, 0);
+		return listdcl(&base, store, qlf, ns, 0);
 	}
 }
 
@@ -389,11 +384,9 @@
 void
 type_name(struct ctype *tp)
 {
-	struct qualifier qlf;
-	char store = 0;
+	char store = 0, qlf = 0;
 
 	initctype(tp);
-	initqlf(&qlf);
 
 	if (!specifier(tp, &store, &qlf))
 		return;
--- a/lex.c
+++ b/lex.c
@@ -141,7 +141,7 @@
 		{"_Imaginary", TYPE, IMAGINARY},
 		{"long", TYPE, LONG},
 		{"register", STORAGE, REGISTER},
-		{"restricted", RESTRICT, RESTRICT},
+		{"restrict", TQUALIFIER, RESTRICT},
 		{"return", RETURN, RETURN},
 		{"short", TYPE, SHORT},
 		{"signed", TYPE, SIGNED},
--- a/symbol.h
+++ b/symbol.h
@@ -17,11 +17,6 @@
 	NS_TAG
 };
 
-struct qualifier {
-	bool c_const : 1;
-	bool c_volatile : 1;
-	bool defined: 1;
-};
 
 struct ctype {
 	unsigned type : 5;
@@ -45,7 +40,7 @@
 struct symbol {
 	struct ctype ctype;
 	char store;
-	struct qualifier qlf;
+	char qlf;
 	unsigned char ctx;
 	unsigned char ns;
 	char *name;
@@ -73,11 +68,9 @@
 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 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 qualifier * initqlf(struct qualifier *qlf);
 
 #ifndef NDEBUG
 extern void ptype(register struct ctype *t);
--- a/tokens.h
+++ b/tokens.h
@@ -13,7 +13,7 @@
 	LDOUBLE, STRUCT, UNION, ENUM, BOOL, ARY, PTR, FTN,
 	COMPLEX, IMAGINARY, BITFLD, TYPENAME, TYPE,
 	/* type qualifier */
-	VOLATILE, CONST, RESTRICT, TQUALIFIER,
+	TQUALIFIER,
 	/* sign specifier */
 	UNSIGNED, SIGNED,
 	/* storage specifier */
@@ -29,12 +29,17 @@
 	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)
+#define TYPEDEF    (1<<0)
+#define EXTERN     (1<<1)
+#define STATIC     (1<<2)
+#define AUTO       (1<<3)
+#define REGISTER   (1<<4)
+#define STORAGE    (1<<5)
+
+#define VOLATILE   (1<<0)
+#define CONST      (1<<1)
+#define RESTRICT   (1<<2)
+#define TQUALIFIER (1<<3)
 
 struct symbol;
 extern struct symbol *yyval;
--- a/types.c
+++ b/types.c
@@ -12,13 +12,6 @@
 static unsigned char stack[NR_DECLARATORS];
 static unsigned char *stackp = stack;
 
-struct qualifier *
-initqlf(struct qualifier *qlf)
-{
-	memset(qlf, 0, sizeof(*qlf));
-	return qlf;
-}
-
 struct ctype *
 initctype(register struct ctype *tp)
 {
@@ -201,30 +194,6 @@
 two_or_more:
 	err = "two or more basic types";
 error:	error(err, yytext);
-}
-
-struct qualifier *
-qualifier(register struct qualifier *qlf, unsigned char mod)
-{
-	switch (mod) {
-	case CONST:
-		if (options.repeat && qlf->c_const)
-			goto duplicated;
-		qlf->c_const = 1;
-		break;
-	case VOLATILE:
-		if (options.repeat && qlf->c_volatile)
-			goto duplicated;
-		qlf->c_volatile = 1;
-		break;
-	default:
-		assert(0);
-	}
-
-	qlf->defined = 1;
-	return qlf;
-duplicated:
-	error("duplicated '%s'", yytext);
 }
 
 #ifndef NDEBUG