This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ alternative tokens in the preprocessor


Upon re-reading the standard, it occured to me that 'and', 'bitor'
etc. are not keywords in C++; they are digraphs. As the result, the
following conditional should be accepted

#define a 1
#define b 2
#if a and b
int i=0;
#endif

This is currently rejected by g++; this patch fixes that. Since the
spelling of the tokens is the alternative one, preprocessor output
still has the alternative tokens.

Ok to install?

Regards,
Martin

2000-07-18  Martin v. Löwis  <loewis@informatik.hu-berlin.de>

	* cpplex.c (cp_alternative_tokens): New array.
	(parse_name): Parse alternative C++ tokens as the original ones.
	(spell_token): Spell them as alternative ones.

Index: cpplex.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cpplex.c,v
retrieving revision 1.76
diff -u -r1.76 cpplex.c
--- cpplex.c	2000/07/16 13:35:23	1.76
+++ cpplex.c	2000/07/18 07:25:03
@@ -1070,6 +1070,26 @@
     }
 }
 
+static struct alternative_names
+{
+  unsigned int length;
+  const char *name;
+  ENUM_BITFIELD(cpp_ttype) type;
+} cp_alternative_tokens[] = {
+  { 2, "or", CPP_OR_OR },
+  { 3, "and", CPP_AND_AND },
+  { 3, "not", CPP_NOT },
+  { 3, "xor", CPP_XOR },
+  { 5, "bitor", CPP_OR },
+  { 5, "compl", CPP_COMPL },
+  { 5, "or_eq", CPP_OR_EQ },
+  { 6, "and_eq", CPP_AND_EQ },
+  { 6, "bitand", CPP_AND },
+  { 6, "not_eq", CPP_NOT_EQ },
+  { 6, "xor_eq", CPP_XOR_EQ },
+  { 0, 0, 0}
+};
+
 /* Parse (append) an identifier.  */
 static const U_CHAR *
 parse_name (pfile, tok, cur, rlimit)
@@ -1106,6 +1126,26 @@
       name = newname;
     }
 
+  if (CPP_OPTION (pfile, cplusplus) && len <= 6)
+    {
+      int i, cmp;
+      for (i=0; cp_alternative_tokens[i].length; i++)
+	{
+	  if (len > cp_alternative_tokens[i].length)
+	    continue;
+	  if (len < cp_alternative_tokens[i].length)
+	    break;
+	  cmp = strncmp ((char*)name, cp_alternative_tokens[i].name, len);
+	  if (cmp > 0)
+	    continue;
+	  if (cmp < 0)
+	    break;
+	  tok->type = cp_alternative_tokens[i].type;
+	  tok->flags |= DIGRAPH;
+	  return cur;
+	} 
+    }
+
   tok->val.node = cpp_lookup (pfile, name, len);
   return cur;
 }
@@ -1964,7 +2004,18 @@
 	unsigned char c;
 
 	if (token->flags & DIGRAPH)
-	  spelling = digraph_spellings[token->type - CPP_FIRST_DIGRAPH];
+	  {
+	    int num = token->type - CPP_FIRST_DIGRAPH;
+	    if (num >= 0 && num < 6)
+	      spelling = digraph_spellings[num];
+	    else
+	      for (num = 0; 1; num++)
+		if (token->type == cp_alternative_tokens[num].type)
+		  {
+		    spelling = (U_CHAR*)cp_alternative_tokens[num].name;
+		    break;
+		  }
+	  }
 	else
 	  spelling = token_spellings[token->type].spelling;
 	
@@ -2606,6 +2657,14 @@
 {
   enum cpp_ttype a = token1->type, b = token2->type;
   int cxx = CPP_OPTION (pfile, cplusplus);
+
+  if (token1->flags & DIGRAPH 
+      && (a < CPP_FIRST_DIGRAPH || a > CPP_FIRST_DIGRAPH+6))
+    a = CPP_NAME;
+
+  if (token2->flags & DIGRAPH 
+      && (b < CPP_FIRST_DIGRAPH || b > CPP_FIRST_DIGRAPH+6))
+    b = CPP_NAME;    
 
   if (a <= CPP_LAST_EQ && b == CPP_EQ)
     return a + (CPP_EQ_EQ - CPP_EQ);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]