shithub: scc

Download patch

ref: 242c473f7221643384498dd67ee2717f31482ffd
parent: 94fd29519bd9650953b1f9b67ae62c628678297d
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu May 31 17:55:36 EDT 2012

Added support for qualifiers in pointer types

--- a/decl.c
+++ b/decl.c
@@ -198,32 +198,43 @@
 
 void decl(void)
 {
-	unsigned char ns = 0;
-	unsigned char qlf[PTRLEVEL_MAX];
+	unsigned char qlf[PTRLEVEL_MAX], *bp, *lim;
 
 	puts("decl");
-	for (ns = 0; yytoken == '*'; ns++) {
-		if (ns == PTRLEVEL_MAX)
-			error("Too much indirection levels");
+	lim = qlf + PTRLEVEL_MAX;
+	for (bp = qlf; yytoken == '*' && bp != lim; ++bp) {
+		*bp = 0;
+	repeat_qlf:
 		switch (gettok()) {
 		case CONST:
-			if (!(qlf[ns] ^= 2))
+			if (!(*bp ^= 1))
 				goto duplicated;
-			continue;
+			goto repeat_qlf;
 		case RESTRICTED:
-			if (!(qlf[ns] ^= 4))
+			if (!(*bp ^= 2))
 				goto duplicated;
-			continue;
+			goto repeat_qlf;
 		case VOLATILE:
-			if (!(qlf[ns] ^= 8))
+			if (!(*bp ^= 4))
 				goto duplicated;
-			continue;
+			goto repeat_qlf;
+		default:
+			break;
 		}
 	}
+
+	if (bp == lim)
+		error("Too much indirection levels");
+
 	dirdcl();
 
-	if (ns)
-		push(PTR);	/* TODO: pointer qualifiers */
+	while (bp-- != qlf) {
+		if (*bp & 1)  push(CONST);
+		if (*bp & 2)  push(RESTRICTED);
+		if (*bp & 4)  push(VOLATILE);
+		push(PTR);
+	}
+
 	printf("leaving dcl %c\n", yytoken);
 	return;
 
--- a/types.c
+++ b/types.c
@@ -26,7 +26,8 @@
 struct type *mktype(register struct type *base, unsigned  char op)
 {
 	register struct type **ptr, *nt;
-	assert(op == PTR || op == ARY || op == FTN);
+	assert(op == PTR      || op == ARY	  || op == FTN ||
+	       op == VOLATILE || op == RESTRICTED || op == CONST);
 
 	switch (op) {
 	case PTR:
@@ -38,6 +39,15 @@
 	case FTN:
 		ptr = &base->ftn;
 		break;
+	case VOLATILE:
+		ptr = &base->vltl;
+		break;
+	case RESTRICTED:
+		ptr = &base->rstr;
+		break;
+	case CONST:
+		ptr = &base->cnst;
+		break;
 	}
 	if (*ptr)  return *ptr;
 
@@ -68,6 +78,16 @@
 			break;
 		case FTN:
 			fputs("function that returns ", stdout);
+			break;
+		case VOLATILE:
+			fputs("volatile ", stdout);
+			break;
+			break;
+		case RESTRICTED:
+			fputs("restricted ", stdout);
+			break;
+		case CONST:
+			fputs("const ", stdout);
 			break;
 		default: {
 				static char *type, *sign;
--- a/types.h
+++ b/types.h
@@ -3,11 +3,15 @@
 
 
 struct type {
-	unsigned char op;
+	unsigned op    : 5;
 	struct type *base;
-	struct type *ary;               /* array */
-	struct type *ptr;		/* pointer */
-	struct type *ftn;		/* function */
+	struct type *ary;		      /* array */
+	struct type *ptr;		      /* pointer */
+	struct type *ftn;		      /* function */
+	struct type *cnst;		      /* const */
+	struct type *vltl;		      /* volatile */
+	struct type *rstr;		      /* restricted */
+
 	union  {
 		struct {
 			unsigned btype : 4;
@@ -37,13 +41,12 @@
 #define T_ULLONG  (&tullong)
 #define T_VOID    (&tvoid)
 
+#define ARY		1
+#define PTR		2
+#define FTN		3
 
-#define ARY             1
-#define PTR             2
-#define FTN             3
-#define T_CONST           8
-#define T_RESTRICTED     16
-#define T_VOLATILE       32
+#define QLF(x)   (VOLATILE - x + 1)
+
 
 struct type *mktype(register struct type *base, unsigned  char op);