commit 242c473f7221643384498dd67ee2717f31482ffd
parent 94fd29519bd9650953b1f9b67ae62c628678297d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 31 May 2012 21:55:36 +0200
Added support for qualifiers in pointer types
Diffstat:
M | decl.c | | | 37 | ++++++++++++++++++++++++------------- |
M | types.c | | | 22 | +++++++++++++++++++++- |
M | types.h | | | 23 | +++++++++++++---------- |
3 files changed, 58 insertions(+), 24 deletions(-)
diff --git a/decl.c b/decl.c
@@ -198,32 +198,43 @@ incorrect_sign:
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;
diff --git a/types.c b/types.c
@@ -26,7 +26,8 @@ struct type tvoid = {.btype = VOID, .sign = 0};
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 @@ struct type *mktype(register struct type *base, unsigned char op)
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;
@@ -69,6 +79,16 @@ void ptype(register struct type *t)
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;
diff --git 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 @@ extern struct type tulong, tllong, tullong, tvoid;
#define T_ULLONG (&tullong)
#define T_VOID (&tvoid)
+#define ARY 1
+#define PTR 2
+#define FTN 3
+
+#define QLF(x) (VOLATILE - x + 1)
-#define ARY 1
-#define PTR 2
-#define FTN 3
-#define T_CONST 8
-#define T_RESTRICTED 16
-#define T_VOLATILE 32
struct type *mktype(register struct type *base, unsigned char op);