scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit ee09d8609cd1439aa67d36c037df65fa92b132ba
parent 8b93ef36c624455eff29470aa7c416f8450f7a5a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 11 Jul 2014 16:14:33 +0200

Add token for types created by typedef

There were different places where the code was asking 'in case
of type and typedef type', so it was not a good idea to use the
TYPE token in this case. This solution avoids a lot of code and
makes the code clearer.

Diffstat:
Mcc1/cc1.h | 2+-
Mcc1/decl.c | 36+++++++++++++++---------------------
Mcc1/expr.c | 30+++++++++++++++++++++---------
Mcc1/stmt.c | 8++++----
4 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -123,7 +123,7 @@ extern Type *voidtype, *pvoidtype, *booltype, enum { - FTN = 1, ENUM, TYPENAME, VOID, FLOAT, INT, BOOL, + FTN = 1, ENUM, TYPEIDEN, VOID, FLOAT, INT, BOOL, STRUCT, UNION, PTR, ARY, CHAR, DOUBLE, SHORT, LONG, COMPLEX, UNSIGNED, SIGNED }; diff --git a/cc1/decl.c b/cc1/decl.c @@ -68,14 +68,13 @@ directdcl(struct dcldata *dp, int8_t flags) dp = declarator0(dp, flags); expect(')'); } else if (flags) { - if (yytoken == IDEN || - yytoken == TYPE && yylval.token == TYPENAME) { + if (yytoken == IDEN || yytoken == TYPEIDEN) sym = newiden(); - } else if (flags & ID_EXPECTED) { + else if (flags & ID_EXPECTED) unexpected(); - } else { + else sym = install("", NS_IDEN); - } + dp->op = IDEN; dp->u.sym = sym; ++dp; @@ -180,16 +179,18 @@ specifier(int8_t *sclass) goto invalid_type; next(); continue; + case TYPEIDEN: + if (type) + goto check_types; + tp = yylval.sym->type; + p = &type; + break; case TYPE: switch (yylval.token) { case ENUM: dcl = enumdcl; p = &type; break; case STRUCT: case UNION: dcl = structdcl; p = &type; break; - case TYPENAME: - if (type) - goto check_types; - tp = yylval.sym->type; case VOID: case BOOL: case CHAR: case INT: case FLOAT: case DOUBLE: p = &type; break; @@ -300,7 +301,7 @@ fielddcl(Type *base) switch (yytoken) { case SCLASS: error("storage class '%s' in struct/union field", yytext); - case IDEN: case TYPE: case TQUALIFIER: + case IDEN: case TYPE: case TYPEIDEN: case TQUALIFIER: tp = specifier(NULL); case ';': break; @@ -326,17 +327,12 @@ newtag(uint8_t tag) register Type *tp; switch (yytoken) { - case TYPE: - if (yylval.token != TYPENAME) - goto no_tag; - /* pass through */ - case IDEN: + case IDEN: case TYPEIDEN: if ((sym = lookup(yytext, NS_TAG)) == NULL) sym = install(yytext, NS_TAG); next(); break; default: - no_tag: sym = install("", NS_TAG); break; } @@ -418,8 +414,7 @@ decl(void) switch (sclass) { case TYPEDEF: - sym->token = TYPE; - sym->u.token = TYPENAME; + sym->token = TYPEIDEN; continue; case STATIC: sym->s.isstatic = 1; @@ -475,7 +470,7 @@ extdecl(void) extern Symbol *curfun; switch (yytoken) { - case IDEN: case TYPE: case SCLASS: case TQUALIFIER: + case IDEN: case TYPE: case TYPEIDEN: case SCLASS: case TQUALIFIER: base = specifier(&sclass); if (accept(';')) return; @@ -496,8 +491,7 @@ extdecl(void) sym->s.isdefined = 0; break; case TYPEDEF: - sym->token = TYPE; - sym->u.token = TYPENAME; + sym->token = TYPEIDEN; continue; } diff --git a/cc1/expr.c b/cc1/expr.c @@ -494,18 +494,35 @@ postfix(void) static Node *unary(void); static Type * -typeunary(void) +typeof(Node *np) { Type *tp; - Node *np; - if ((np = unary()) == NULL) + if (np == NULL) unexpected(); tp = np->type; /* TODO: free np */ return tp; } +static Type * +sizeexp(void) +{ + register Type *tp; + + expect('('); + switch (yytoken) { + case TYPE: case TYPEIDEN: + tp = typename(); + break; + default: + tp = typeof(unary()); + break; + } + expect(')'); + return tp; +} + static Node *cast(void); static Node * @@ -518,12 +535,7 @@ unary(void) switch (yytoken) { case SIZEOF: next(); - if (accept('(')) { - tp = (yytoken == TYPE) ? typename() : typeunary(); - expect(')'); - } else { - tp = typeunary(); - } + tp = (yytoken == '(') ? sizeexp() : typeof(unary()); return sizeofcode(tp); case INC: case DEC: op = (yytoken == INC) ? OA_ADD : OA_SUB; diff --git a/cc1/stmt.c b/cc1/stmt.c @@ -171,7 +171,7 @@ static void Label(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) { switch (yytoken) { - case IDEN: case TYPE: + case IDEN: case TYPEIDEN: emitlabel(label(yytext, 1)); next(); expect(':'); @@ -302,8 +302,8 @@ compound(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) case '}': next(); return; - case TYPE: - if (yylval.token == TYPENAME && ahead() == ':') + case TYPEIDEN: + if (ahead() == ':') goto statement; /* pass through */ case SCLASS: case TQUALIFIER: @@ -335,7 +335,7 @@ stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) case CASE: fun = Case; break; case DEFAULT: fun = Default; break; default: fun = stmtexp; break; - case TYPE: case IDEN: + case TYPEIDEN: case IDEN: fun = (ahead() == ':') ? Label : stmtexp; break; }