commit 951024c4481a3f63bfab9a83364d6861f16ee5d9
parent d247bc3fa770720335e31b8d3c735200b2484c30
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 11 Mar 2014 17:36:05 +0100
Change storage codification
This form of codificate storage makes trivial all the checks in
declarations.
Diffstat:
M | decl.c | | | 31 | ++++++++++++++++--------------- |
M | expr.c | | | 11 | +++++------ |
M | symbol.h | | | 13 | +------------ |
M | tokens.h | | | 12 | +++++++++--- |
M | types.c | | | 53 | +---------------------------------------------------- |
5 files changed, 32 insertions(+), 88 deletions(-)
diff --git a/decl.c b/decl.c
@@ -172,9 +172,9 @@ enumdcl(struct ctype *base)
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 @@ specifier(register struct ctype *tp,
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 @@ specifier(register struct ctype *tp,
else
structdcl(tp);
return true;
- case TYPEDEF:
+ case TYPENAME:
tp->base = &yyval->ctype;
break;
}
@@ -208,7 +211,7 @@ specifier(register struct ctype *tp,
check_type:
if (!tp->defined) {
- if (!store->defined &&
+ if (*store &&
!qlf->defined &&
curctx != CTX_OUTER &&
nested_tags == 0) {
@@ -285,7 +288,7 @@ initializer(register struct ctype *tp)
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 @@ listdcl(struct ctype *base,
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 @@ struct node *
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,18 +382,17 @@ decl(unsigned char ns)
if (yytoken == ';')
return NULL;
default:
- return listdcl(&base, &store, &qlf, ns, 0);
+ return listdcl(&base, store, &qlf, ns, 0);
}
}
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))
diff --git a/expr.c b/expr.c
@@ -129,19 +129,18 @@ call_unary:
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();
}
diff --git a/symbol.h b/symbol.h
@@ -23,15 +23,6 @@ struct qualifier {
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 ctype {
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 del_ctx(void);
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
diff --git a/tokens.h b/tokens.h
@@ -11,13 +11,13 @@ enum tokens {
/* 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 @@ enum tokens {
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;
diff --git a/types.c b/types.c
@@ -28,17 +28,6 @@ initctype(register struct ctype *tp)
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 @@ check_sign: switch (type) {
goto invalid_sign;
}
break;
- case TYPEDEF:
+ case TYPENAME:
assert(!type);
if (tp->c_signed || tp->c_unsigned)
goto invalid_sign;
@@ -238,46 +227,6 @@ 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
#include <stdio.h>