scc

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

commit 18bc293eda5e66a9cd3f86d9dcb1c987de599779
parent b82f7284d496438fd63cff37719ff25d9f9dbd61
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  5 Oct 2015 15:39:32 +0200

Add support for define() in #if

This is really stupidity of ansi c comitee, but ok, we need it.

Diffstat:
Mcc1/cpp.c | 4+++-
Mcc1/expr.c | 40+++++++++++++++++++++++++++++++++-------
2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/cc1/cpp.c b/cc1/cpp.c @@ -228,7 +228,9 @@ expand(char *begin, Symbol *sym) char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE]; macroname = sym->name; - if (!(sym->flags & ISDECLARED)) { + if ((sym->flags & ISDECLARED) == 0) { + if (namespace == NS_CPP && !strcmp(sym->name, "defined")) + return 0; /* we found a 'defined in an #if */ /* * This case happens in #if were macro not defined must * be expanded to 0 diff --git a/cc1/expr.c b/cc1/expr.c @@ -496,6 +496,32 @@ negation(char op, Node *np) } } +static Symbol * +notdefined(Symbol *sym) +{ + int isdef; + + if (namespace == NS_CPP && !strcmp(sym->name, "defined")) { + disexpand = 1; + next(); + expect('('); + sym = yylval.sym; + expect(IDEN); + expect(')'); + + isdef = (sym->flags & ISDEFINED) != 0; + sym = newsym(NS_IDEN); + sym->type = inttype; + sym->flags |= ISCONSTANT; + sym->u.i = isdef; + disexpand = 0; + return sym; + } + errorp("'%s' undeclared", yytext); + sym->type = inttype; + return install(sym->ns, yylval.sym); +} + /************************************************************* * grammar functions * *************************************************************/ @@ -505,18 +531,18 @@ primary(void) Node *np; Symbol *sym; + sym = yylval.sym; switch (yytoken) { case CONSTANT: - np = constnode(yylval.sym); + constant: + np = constnode(sym); next(); break; case IDEN: - sym = yylval.sym; - if ((sym->flags & ISDECLARED) == 0) { - errorp("'%s' undeclared", yytext); - sym->type = inttype; - install(sym->ns, yylval.sym); - } + if ((sym->flags & ISDECLARED) == 0) + sym = notdefined(sym); + if (sym->flags & ISCONSTANT) + goto constant; sym->flags |= ISUSED; np = varnode(sym); next();