scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 64122b83087c57a0fc5eb7a272816212f4994ab1
parent f7bbcdf04512a97a853a07c9bdc635566f0f735a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed,  6 Aug 2014 09:11:56 +0200

Move type checks to ctype()

ctype() has to switch to all the basic types, so it is the best
place for making the correct test for any of them. This patch
increases a bit the size of the code, but it improves the
speed and do the correct thing in the correct place.

Diffstat:
Mcc1/decl.c | 26++++++++------------------
Mcc1/types.c | 38+++++++++++++++++++++++++++++++++-----
2 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/cc1/decl.c b/cc1/decl.c @@ -198,7 +198,7 @@ specifier(int8_t *sclass) continue; case TYPEIDEN: if (type) - goto check_types; + goto return_type; tp = yylval.sym->type; p = &type; break; @@ -223,31 +223,21 @@ specifier(int8_t *sclass) } break; default: - goto check_types; + goto return_type; } if (*p) goto invalid_type; *p = yylval.token; - if (dcl) + if (dcl) { + if (size || sign) + goto invalid_type; tp = aggregate(dcl); - else + } else { next(); - } - -check_types: - if (!type) { - if (!sign && !size) { - warn(options.implicit, - "type defaults to 'int' in declaration"); } - type = INT; - } - if (sign && type != INT && type != CHAR || - size == SHORT && type != INT || - size == LONG && type != INT && type != DOUBLE || - size == LONG+LONG && type != INT) { - goto invalid_type; } + +return_type: if (sclass) *sclass = cls; if (!tp) diff --git a/cc1/types.c b/cc1/types.c @@ -118,18 +118,33 @@ Type Type * ctype(int8_t type, int8_t sign, int8_t size) { - if (type == DOUBLE) - type = FLOAT, size += LONG; - switch (type) { case CHAR: - if (sign == 0) + if (size) + goto invalid_type; + switch (sign) { + case 0: return chartype; - return (sign == UNSIGNED) ? uchartype : schartype; + case SIGNED: + return schartype; + case UNSIGNED: + return uchartype; + } + break; case VOID: + if (size || sign) + goto invalid_type; return voidtype; case BOOL: + if (size || sign) + goto invalid_type; return booltype; + case 0: + if (!sign && !size) { + warn(options.implicit, + "type defaults to 'int' in declaration"); + } + /* fallthrough */ case INT: switch (size) { case 0: @@ -142,7 +157,17 @@ ctype(int8_t type, int8_t sign, int8_t size) return (sign == UNSIGNED) ? ullongtype : llongtype; } break; + case DOUBLE: + if (size == LONG+LONG) + goto invalid_type; + size += LONG; + goto floating; case FLOAT: + if (size == LONG+LONG) + goto invalid_type; + floating: + if (sign) + goto invalid_type; switch (size) { case 0: return floattype; @@ -155,6 +180,9 @@ ctype(int8_t type, int8_t sign, int8_t size) } fputs("internal type error, aborting\n", stderr); abort(); + +invalid_type: + error("invalid type specification"); } Type *