This will allow such things as
  constexpr std::complex<float>
  operator""if(long double imag);

OK after testing completes on x86_64-linux.

Ed

gcc/cp:

2013-06-25  Ed Smith-Rowland  <3dw...@verizon.net>

        * gcc/cp/parser.c (cp_parser_operator()): Parse user-defined string
        literal as literal operator.


gcc/testsuite:

2013-06-25  Ed Smith-Rowland  <3dw...@verizon.net>

        * gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C: Adjust.
        * gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C: New.
        * gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C: New.
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c     (revision 200342)
+++ gcc/cp/parser.c     (working copy)
@@ -12591,6 +12589,12 @@
              return cp_literal_operator_id (name);
            }
        }
+      else if (token->type == CPP_KEYWORD)
+       {
+         error ("unexpected keyword;"
+                " Remove space between quotes and suffix identifier");
+         return error_mark_node;
+       }
       else
        {
          error ("expected suffix identifier");
@@ -12598,7 +12602,32 @@
        }
 
     case CPP_STRING_USERDEF:
-      error ("missing space between %<\"\"%> and suffix identifier");
+      if (cxx_dialect == cxx98)
+       maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
+      {
+       tree string_tree = USERDEF_LITERAL_VALUE (token->u.value);
+       if (TREE_STRING_LENGTH (string_tree) > 2)
+         {
+           error ("expected empty string after %<operator%> keyword");
+           return error_mark_node;
+         }
+       id = USERDEF_LITERAL_SUFFIX_ID (token->u.value);
+       /* Consume the user-defined string literal.  */
+       cp_lexer_consume_token (parser->lexer);
+       if (id != error_mark_node)
+         {
+           const char *name = IDENTIFIER_POINTER (id);
+           return cp_literal_operator_id (name);
+         }
+       else
+         return error_mark_node;
+      }
+
+    case CPP_WSTRING_USERDEF:
+    case CPP_STRING16_USERDEF:
+    case CPP_STRING32_USERDEF:
+    case CPP_UTF8STRING_USERDEF:
+      error ("invalid encoding prefix in literal operator");
       return error_mark_node;
 
     default:
Index: gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C      (revision 200342)
+++ gcc/testsuite/g++.dg/cpp0x/udlit-nospace-neg.C      (working copy)
@@ -1,3 +1,5 @@
 // { dg-options "-std=c++0x" }
 
-float operator ""_abc(const char*); // { dg-error "missing space between|and 
suffix identifier" }
+float operator ""_abc(const char*);
+
+int operator""_def(long double);
Index: gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C   (revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/udlit-enc-prefix-neg.C   (working copy)
@@ -0,0 +1,17 @@
+// { dg-options -std=c++1y }
+
+int
+operator L""Ls(unsigned long long) // { dg-error "invalid encoding prefix in 
literal operator" }
+{ return 0; }
+
+int
+operator u""s16(unsigned long long) // { dg-error "invalid encoding prefix in 
literal operator" }
+{ return 0; }
+
+int
+operator U""s32(unsigned long long) // { dg-error "invalid encoding prefix in 
literal operator" }
+{ return 0; }
+
+int
+operator u8""u8s(unsigned long long) // { dg-error "invalid encoding prefix in 
literal operator" }
+{ return 0; }
Index: gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C   (revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/udlit-userdef-string.C   (working copy)
@@ -0,0 +1,7 @@
+// { dg-options -std=c++1y }
+
+#include "complex_literals.h"
+
+auto cx = 1.1if;
+
+auto cn = 123if;

Reply via email to