ref: 8974b56350753b5677ed0042471cc068159a328b
parent: ec361b9959f7434a634a1c7e6dc1315b890a9c63
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Sep 27 11:27:47 EDT 2016
[cc1] Add support for defined in cpp
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -838,8 +838,10 @@
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 @@
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;
}
--- /dev/null
+++ b/cc1/tests/test066.c
@@ -1,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