scc

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

commit b93fb91a6000311ebf202fa2d618e1f9e2158bbd
parent 56b94fe84a71df35ca1cbdd299985b2fe480c3ba
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 27 Sep 2016 15:27:47 +0200

[cc1] Add support for defined in cpp

Diffstat:
Mcc1/expr.c | 21+++++++++++++++++++++
Acc1/tests/test066.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/cc1/expr.c b/cc1/expr.c @@ -838,8 +838,10 @@ static Node * unary(int needdecay) { Node *(*fun)(char, Node *), *np; + Symbol *sym; char op; Type *tp; + int paren; switch (yytoken) { case '!': op = 0; fun = negation; break; @@ -860,7 +862,26 @@ unary(int needdecay) next(); np = incdec(unary(1), op); goto chk_decay; + case IDEN: + case TYPEIDEN: + if (lexmode != CPPMODE || strcmp(yylval.sym->name, "defined")) + goto call_postfix; + disexpand = 1; + next(); + paren = accept('('); + if (yytoken != IDEN && yytoken != TYPEIDEN) + cpperror("operator 'defined' requires an identifier"); + if (yytoken == TYPEIDEN || !(yylval.sym->flags & SDECLARED)) + sym = zero; + else + sym = one; + disexpand = 0; + next(); + if (paren) + expect(')'); + return constnode(sym); default: + call_postfix: np = postfix(primary()); goto chk_decay; } diff --git a/cc1/tests/test066.c b/cc1/tests/test066.c @@ -0,0 +1,55 @@ +/* See LICENSE file for copyright and license details. */ + +/* +name: TEST066 +description: Test cpp defined operator +error: +test066.c:53: error: operator 'defined' requires an identifier +test066.c:53: error: expected ')' before '<EOF>' +output: +G1 I "x ( + #I0 +) +G3 I F "main +{ +\ + h #I0 +*/ + + +#if defined X +X +#endif + +#if defined(X) +X +#endif + +#if X +X +#endif + +#define X 0 + +#if X +X +#endif + +#if defined(X) +int x = 0; +#endif + +#undef X +#define X 1 + +#if X +int +main() +{ + return 0; +} +#endif + +#if defined (1) +#error 1 is defined +#endif