ref: bbb23c1bab015ae2a89d19ce00d2c29894ec8904
parent: b0126dcc1e00f427b21754693c8d6dcbf5101e58
author: Roberto E. Vargas Caballero <[email protected]>
date: Wed Oct 30 17:21:27 EDT 2013
Pass type struct to specifier This is the first step for removing the storage specifier from the type struct. We need this step because we will have a pointer to the type and a pointer to the storage, while specifier was a void function returning a pointer to ctype, and it is no longer valid. This change implies we can not test against NULL in specifier, because it is not going to be true anymore, so we introduce two new fields, that indicate if type or storage are defined. This fields are going to be splitted later in two different structs.
--- a/decl.c
+++ b/decl.c
@@ -75,24 +75,23 @@
tp->sym = sym;
}
-static struct ctype *specifier(void);
+static bool specifier(struct ctype *);
static struct ctype *
fielddcl(unsigned char ns)
{
- register struct ctype *tp, *base;
+ struct ctype base;
+ register struct ctype *tp;
- if (!(base = specifier())) {
- base = ctype(NULL, INT);
- warn(options.implicit,
- "data definition has no type or storage class");
- }
- if (HAS_STORAGE(base))
+ initctype(&base);
+ specifier(&base);
+
+ if (HAS_STORAGE(&base))
error("storage specifier in a struct/union field declaration");
do {
- declarator(base, ns);
- tp = decl_type(base);
+ declarator(&base, ns);
+ tp = decl_type(&base);
if (accept(':')) {
expect(CONSTANT);
switch (tp->type) {
@@ -108,7 +107,6 @@
cursym->ctype = tp;
} while (accept(','));
- delctype(base);
expect(';');
return tp;
}
@@ -165,11 +163,9 @@
return base;
}
-struct ctype *
-specifier(void)
+bool
+specifier(register struct ctype *tp)
{
- register struct ctype *tp = NULL;
-
for (;; next()) {
switch (yytoken) {
case TYPEDEF: case EXTERN: case STATIC: case AUTO:
@@ -192,7 +188,7 @@
next();
return structdcl(tp);
case IDEN:
- if (!tp || !tp->type) {
+ if (!tp->tdef && !tp->sdef) {
register struct symbol *sym;
sym = lookup(yytext, NS_IDEN);
@@ -205,16 +201,18 @@
/* it is not a type name */
default:
check_type:
- if (!tp) {
+ if (!tp->tdef && !tp->sdef) {
+ /* TODO: Allow no type in structs and union */
if (curctx != CTX_OUTER || yytoken != IDEN)
- return NULL;
+ return false;
tp = ctype(tp, INT);
+ tp = storage(tp, STATIC);
warn(options.implicit,
"data definition has no type or storage class");
- } else if (!tp->type) {
+ } else if (!tp->tdef) {
warn(options.implicit,
"type defaults to 'int' in declaration");
- tp->type = INT;
+ tp = ctype(tp, INT);
}
if (!tp->c_signed && !tp->c_unsigned) {
switch (tp->type) {
@@ -227,7 +225,7 @@
tp->c_signed = 1;
}
}
- return tp;
+ return true;
}
}
}
@@ -315,22 +313,24 @@
struct node *
decl(void)
{
- register struct ctype *base;
+ struct ctype base;
struct node *np;
-repeat: if (!(base = specifier()))
+repeat: initctype(&base);
+
+ if (!specifier(&base))
return NULL;
if (accept(';')) {
- register unsigned char type = base->type;
+ register unsigned char type = base.type;
switch (type) {
case STRUCT: case UNION: case ENUM:
- if (HAS_STORAGE(base) || HAS_QUALIF(base)) {
+ if (HAS_STORAGE(&base) || HAS_QUALIF(&base)) {
warn(options.useless,
"useless storage class specifier in empty declaration");
}
- if (!base->sym && type != ENUM) {
+ if (base.sym && type != ENUM) {
warn(options.useless,
"unnamed struct/union that defines no instances");
}
@@ -338,11 +338,9 @@
warn(options.useless,
"useless type name in empty declaration");
}
- delctype(base);
goto repeat;
}
- np = listdcl(base);
- delctype(base);
+ np = listdcl(&base);
return np;
}
--- a/symbol.h
+++ b/symbol.h
@@ -30,6 +30,8 @@
bool c_unsigned : 1;
bool c_signed : 1;
bool forward : 1;
+ bool tdef: 1;
+ bool sdef: 1;
union {
unsigned len;
struct {
@@ -75,6 +77,7 @@
extern struct ctype *storage(struct ctype *tp, unsigned char mod);
extern void delctype(struct ctype *tp);
extern unsigned char hash(register const char *s);
+extern void initctype(register struct ctype *tp);
#ifndef NDEBUG
extern void ptype(register struct ctype *t);
--- a/types.c
+++ b/types.c
@@ -60,6 +60,7 @@
default:
assert(0);
}
+ tp->tdef = 1;
return tp;
}
@@ -174,6 +175,7 @@
default:
assert(0);
}
+ tp->tdef = 1;
tp->type = type;
return tp;
@@ -196,6 +198,8 @@
tp = xmalloc(sizeof(*tp));
initctype(tp);
}
+
+ tp->sdef = 1;
switch (mod) {
case TYPEDEF:
if (tp->c_typedef)
@@ -252,6 +256,8 @@
goto bad_typedef;
tp->c_volatile = 1;
return tp;
+ default:
+ assert(0);
}
bad_typedef:
error("typedef specifies type qualifier");