re PR c++/14875 (When using 'or' keyword, the error message speaks of a '||' token)
authorManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 22 Apr 2009 15:32:18 +0000 (15:32 +0000)
committerManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 22 Apr 2009 15:32:18 +0000 (15:32 +0000)
2009-04-22  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

PR c++/14875
* c-common.c (c_parse_error): Take a token_flags parameter.
Use token_type for the token type instead.
Pass token_flags to cpp_type2name.
* c-common.h (c_parse_error): Update declaration.
* c-parser.c (c_parser_error): Pass 0 as token flags.
libcpp/
* lex.c (cpp_type2name): Take a flags parameter. Call
cpp_named_operator2name for named operators and cpp_digraph2name
for digraphs.
(cpp_digraph2name): New.
(cpp_spell_token): Use it.
(cpp_output_token): Likewise.
* include/cpplib.h (cpp_type2name): Update declaration.
* init.c (cpp_named_operator2name): New.
* internal.h (cpp_named_operator2name): Declare.
cp/
* parser.c (cp_parser_error): Pass token->flags to c_parse_error.
testsuite/
* g++.dg/parse/parser-pr14875.C: New.
* g++.dg/parse/parser-pr14875-2.C: New.
* g++.dg/parse/error6.C: Update match string.

From-SVN: r146589

15 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/error6.C
gcc/testsuite/g++.dg/parse/parser-pr14875-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/parser-pr14875.C [new file with mode: 0644]
libcpp/ChangeLog
libcpp/include/cpplib.h
libcpp/init.c
libcpp/internal.h
libcpp/lex.c

index 1745a365e8624a4cfd2e73484dd3b928e80416cd..f037097d36e849d6946c1f5d840bb79e2d4855e1 100644 (file)
@@ -1,3 +1,12 @@
+2009-04-22  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/14875
+       * c-common.c (c_parse_error): Take a token_flags parameter.
+       Use token_type for the token type instead.
+       Pass token_flags to cpp_type2name.
+       * c-common.h (c_parse_error): Update declaration.
+       * c-parser.c (c_parser_error): Pass 0 as token flags.
+
 2009-04-22  Andrey Belevantsev  <abel@ispras.ru>
 
        PR rtl-optimization/39580
index 3595e552966f0f20e709a5dc514cdd12611edd05..67fe8ad8ebd9718a538785c69700de5ff497609b 100644 (file)
@@ -8167,21 +8167,24 @@ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
    TOKEN, which had the associated VALUE.  */
 
 void
-c_parse_error (const char *gmsgid, enum cpp_ttype token, tree value)
+c_parse_error (const char *gmsgid, enum cpp_ttype token_type, 
+              tree value, unsigned char token_flags)
 {
 #define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
 
   char *message = NULL;
 
-  if (token == CPP_EOF)
+  if (token_type == CPP_EOF)
     message = catenate_messages (gmsgid, " at end of input");
-  else if (token == CPP_CHAR || token == CPP_WCHAR || token == CPP_CHAR16
-          || token == CPP_CHAR32)
+  else if (token_type == CPP_CHAR 
+          || token_type == CPP_WCHAR 
+          || token_type == CPP_CHAR16
+          || token_type == CPP_CHAR32)
     {
       unsigned int val = TREE_INT_CST_LOW (value);
       const char *prefix;
 
-      switch (token)
+      switch (token_type)
        {
        default:
          prefix = "";
@@ -8206,26 +8209,28 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token, tree value)
       free (message);
       message = NULL;
     }
-  else if (token == CPP_STRING || token == CPP_WSTRING || token == CPP_STRING16
-          || token == CPP_STRING32)
+  else if (token_type == CPP_STRING 
+          || token_type == CPP_WSTRING 
+          || token_type == CPP_STRING16
+          || token_type == CPP_STRING32)
     message = catenate_messages (gmsgid, " before string constant");
-  else if (token == CPP_NUMBER)
+  else if (token_type == CPP_NUMBER)
     message = catenate_messages (gmsgid, " before numeric constant");
-  else if (token == CPP_NAME)
+  else if (token_type == CPP_NAME)
     {
       message = catenate_messages (gmsgid, " before %qE");
       error (message, value);
       free (message);
       message = NULL;
     }
-  else if (token == CPP_PRAGMA)
+  else if (token_type == CPP_PRAGMA)
     message = catenate_messages (gmsgid, " before %<#pragma%>");
-  else if (token == CPP_PRAGMA_EOL)
+  else if (token_type == CPP_PRAGMA_EOL)
     message = catenate_messages (gmsgid, " before end of line");
-  else if (token < N_TTYPES)
+  else if (token_type < N_TTYPES)
     {
       message = catenate_messages (gmsgid, " before %qs token");
-      error (message, cpp_type2name (token));
+      error (message, cpp_type2name (token_type, token_flags));
       free (message);
       message = NULL;
     }
index a46da6bcb7d0de0998785bc81eabac01aa1e589a..ec47a023bfc129261cce929a7776f561364a568e 100644 (file)
@@ -1029,7 +1029,7 @@ extern void builtin_define_std (const char *macro);
 extern void builtin_define_with_value (const char *, const char *, int);
 extern void c_stddef_cpp_builtins (void);
 extern void fe_file_change (const struct line_map *);
-extern void c_parse_error (const char *, enum cpp_ttype, tree);
+extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char);
 
 /* Objective-C / Objective-C++ entry points.  */
 
index 676c709cdf2f179a3c7c142c35808fbd76ad8949..ed77098b4d392aa0d5940b493d8f66ccbcd7ca3e 100644 (file)
@@ -573,7 +573,11 @@ c_parser_error (c_parser *parser, const char *gmsgid)
                    CPP_KEYWORD, keywords are treated like
                    identifiers.  */
                 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
-                token->value);
+                /* ??? The C parser does not save the cpp flags of a
+                   token, we need to pass 0 here and we will not get
+                   the source spelling of some tokens but rather the
+                   canonical spelling.  */
+                token->value, /*flags=*/0);
 }
 
 /* If the next token is of the indicated TYPE, consume it.  Otherwise,
index 99c78261654d96a4bafb23ca69acd864abb28bc3..1b67ad87944237816e5c8c36f8b6e7ea0b945e0d 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-22  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/14875
+       * parser.c (cp_parser_error): Pass token->flags to c_parse_error.
+
 2009-04-21  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR c++/35711
index b6b8bf598334d6da3727b9861b1564bdd6ae2e60..fbf211bfb9f311cc994ce4d5294571c23d2fc677 100644 (file)
@@ -2091,7 +2091,7 @@ cp_parser_error (cp_parser* parser, const char* message)
                        CPP_KEYWORD, keywords are treated like
                        identifiers.  */
                     (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
-                    token->u.value);
+                    token->u.value, token->flags);
     }
 }
 
index 6fa530d460cba5b5ae63257f8673a8d59719b1fc..386ce8cae69486b8b4d2036c31ea65f7d0a4be7b 100644 (file)
@@ -1,3 +1,10 @@
+2009-04-22  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/14875
+       * g++.dg/parse/parser-pr14875.C: New.
+       * g++.dg/parse/parser-pr14875-2.C: New.
+       * g++.dg/parse/error6.C: Update match string.
+
 2009-04-22  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/39845
index 81e04e21722e671dcebcbda29484379a7fad0480..8b8424fe30ac306345f25fb3437a5e2027f498b9 100644 (file)
@@ -5,7 +5,7 @@ int f(int not) {
   return 1-not;
 } 
 
-// { dg-error "11:expected ',' or '...' before '!' token" "" { target *-*-* } 4 }
+// { dg-error "11:expected ',' or '...' before 'not' token" "" { target *-*-* } 4 }
 
 // { dg-error "15:expected primary\\-expression before ';' token" "" { target *-*-* } 5 }
 
diff --git a/gcc/testsuite/g++.dg/parse/parser-pr14875-2.C b/gcc/testsuite/g++.dg/parse/parser-pr14875-2.C
new file mode 100644 (file)
index 0000000..3510aac
--- /dev/null
@@ -0,0 +1,31 @@
+// PR 14875: When using 'or' keyword, the error message speaks of a '||' token
+// { dg-do compile }
+// { dg-options "" }
+#define CHECK(x)  void ::x
+  CHECK (and);      // { dg-error "before .and. token" }
+  CHECK (and_eq);   // { dg-error "before .and_eq. token" }
+  CHECK (bitand);   // { dg-error "before .bitand. token" }
+  CHECK (bitor);    // { dg-error "before .bitor. token" }
+  CHECK (compl);    // { dg-error "before .compl. token" }
+  CHECK (not);      // { dg-error "before .not. token" }
+  CHECK (not_eq);   // { dg-error "before .not_eq. token" }
+  CHECK (or);       // { dg-error "before .or. token" }
+  CHECK (or_eq);    // { dg-error "before .or_eq. token" }
+  CHECK (xor);      // { dg-error "before .xor. token" }
+  CHECK (xor_eq);   // { dg-error "before .xor_eq. token" }
+#undef CHECK
+#define CHECK(x)  int x
+  CHECK (<:);     // { dg-error "before .<:. token" }
+  CHECK (:>);     // { dg-error "before .:>. token" }
+#undef CHECK
+#define CHECK(x)  x
+  CHECK (<%);     // { dg-error "before .<%. token" }
+#undef CHECK
+#define CHECK(x)  x x
+  CHECK (%>);     // { dg-error "before .%>. token" }
+#undef CHECK
+#define CHECK(x)  x
+  CHECK (%:);     // { dg-error "stray .%:. " }
+  CHECK (%:%:);   // { dg-error "stray .%:%:. " }
+
+
diff --git a/gcc/testsuite/g++.dg/parse/parser-pr14875.C b/gcc/testsuite/g++.dg/parse/parser-pr14875.C
new file mode 100644 (file)
index 0000000..7a6f061
--- /dev/null
@@ -0,0 +1,20 @@
+// PR 14875: When using 'or' keyword, the error message speaks of a '||' token
+// { dg-do compile }
+// { dg-options "" }
+using namespace std; 
+class Sample 
+{ 
+public: 
+  Sample(); 
+  void or(long Digital);  // { dg-error "before .or. token" }
+}; 
+Sample::Sample() 
+{ 
+} 
+void Sample::or(long Digital) // { dg-error "before .or. token" }
+{ 
+}
index 7fdc737239f052e292edab575e1ea4b7a8f931be..ff720612a5676eb23c5752d5654fb80946e6bad1 100644 (file)
@@ -1,3 +1,16 @@
+2009-04-22  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
+
+       PR c++/14875
+       * lex.c (cpp_type2name): Take a flags parameter. Call
+       cpp_named_operator2name for named operators and cpp_digraph2name
+       for digraphs.
+       (cpp_digraph2name): New.
+       (cpp_spell_token): Use it.
+       (cpp_output_token): Likewise.
+       * include/cpplib.h (cpp_type2name): Update declaration.
+       * init.c (cpp_named_operator2name): New.
+       * internal.h (cpp_named_operator2name): Declare.
+
 2009-04-21  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR c++/13358
index 3aeb035f48f4b530bf91a0d63991f5381621349f..b38d9f43ef5ebbb3e31ed387a2b73d583283cda2 100644 (file)
@@ -841,7 +841,7 @@ extern void cpp_output_line (cpp_reader *, FILE *);
 extern unsigned char *cpp_output_line_to_string (cpp_reader *,
                                                 const unsigned char *);
 extern void cpp_output_token (const cpp_token *, FILE *);
-extern const char *cpp_type2name (enum cpp_ttype);
+extern const char *cpp_type2name (enum cpp_ttype, unsigned char flags);
 /* Returns the value of an escape sequence, truncated to the correct
    target precision.  PSTR points to the input pointer, which is just
    after the backslash.  LIMIT is how much text we have.  WIDE is true
index c21121707d38129d2f1c00bd9ba8a8ec52c83f6d..aef39981792e78cd1faabc933f6a09b70adf291e 100644 (file)
@@ -381,6 +381,24 @@ mark_named_operators (cpp_reader *pfile)
     }
 }
 
+/* Helper function of cpp_type2name. Return the string associated with
+   named operator TYPE.  */
+const char *
+cpp_named_operator2name (enum cpp_ttype type)
+{
+  const struct builtin_operator *b;
+
+  for (b = operator_array;
+       b < (operator_array + ARRAY_SIZE (operator_array));
+       b++)
+    {
+      if (type == b->value)
+       return (const char *) b->name;
+    }
+
+  return NULL;
+}
+
 void
 cpp_init_special_builtins (cpp_reader *pfile)
 {
index 4368ebbe998f1c5a8775b30a012dfa21e17698b4..22e6d238906a46cf52e660dafc091327de101d33 100644 (file)
@@ -570,6 +570,7 @@ extern void _cpp_init_tokenrun (tokenrun *, unsigned int);
 
 /* In init.c.  */
 extern void _cpp_maybe_push_include_file (cpp_reader *);
+extern const char *cpp_named_operator2name (enum cpp_ttype type);
 
 /* In directives.c */
 extern int _cpp_test_assertion (cpp_reader *, unsigned int *);
index 63e291c64c0ea0c8262f489fb92f4c88667cf66c..af5c06a7abcfb3f3ef9be2863f1dde2ad06c0b11 100644 (file)
@@ -1416,6 +1416,13 @@ utf8_to_ucn (unsigned char *buffer, const unsigned char *name)
   return ucn_len;
 }
 
+/* Given a token TYPE corresponding to a digraph, return a pointer to
+   the spelling of the digraph.  */
+static const unsigned char *
+cpp_digraph2name (enum cpp_ttype type)
+{
+  return digraph_spellings[(int) type - (int) CPP_FIRST_DIGRAPH];
+}
 
 /* Write the spelling of a token TOKEN to BUFFER.  The buffer must
    already contain the enough space to hold the token's spelling.
@@ -1435,8 +1442,7 @@ cpp_spell_token (cpp_reader *pfile, const cpp_token *token,
        unsigned char c;
 
        if (token->flags & DIGRAPH)
-         spelling
-           = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH];
+         spelling = cpp_digraph2name (token->type);
        else if (token->flags & NAMED_OP)
          goto spell_ident;
        else
@@ -1499,11 +1505,17 @@ cpp_token_as_text (cpp_reader *pfile, const cpp_token *token)
   return start;
 }
 
-/* Used by C front ends, which really should move to using
-   cpp_token_as_text.  */
+/* Returns a pointer to a string which spells the token defined by
+   TYPE and FLAGS.  Used by C front ends, which really should move to
+   using cpp_token_as_text.  */
 const char *
-cpp_type2name (enum cpp_ttype type)
+cpp_type2name (enum cpp_ttype type, unsigned char flags)
 {
+  if (flags & DIGRAPH)
+    return (const char *) cpp_digraph2name (type);
+  else if (flags & NAMED_OP)
+    return cpp_named_operator2name (type);
+
   return (const char *) token_spellings[type].name;
 }
 
@@ -1521,8 +1533,7 @@ cpp_output_token (const cpp_token *token, FILE *fp)
        int c;
 
        if (token->flags & DIGRAPH)
-         spelling
-           = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH];
+         spelling = cpp_digraph2name (token->type);
        else if (token->flags & NAMED_OP)
          goto spell_ident;
        else