shithub: scc

Download patch

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