DR1473: Do not require a space between operator"" and the ud-suffix in a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 20 Oct 2012 08:41:10 +0000 (08:41 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 20 Oct 2012 08:41:10 +0000 (08:41 +0000)
literal-operator-id.

llvm-svn: 166373

clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseExprCXX.cpp
clang/test/CXX/over/over.oper/over.literal/p8.cpp
clang/test/FixIt/fixit-cxx0x.cpp
clang/test/Parser/cxx11-user-defined-literals.cpp

index 7f46bf0..b670d6e 100644 (file)
@@ -472,9 +472,6 @@ def err_literal_operator_string_prefix : Error<
   "string literal after 'operator' cannot have an encoding prefix">;
 def err_literal_operator_string_not_empty : Error<
   "string literal after 'operator' must be '\"\"'">;
-def err_literal_operator_missing_space : Error<
-  "C++11 requires a space between the \"\" and the user-defined suffix in a "
-  "literal operator">;
 def warn_cxx98_compat_literal_operator : Warning<
   "literal operators are incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
index e478ef4..63fcf34 100644 (file)
@@ -1881,8 +1881,9 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
 
   // Parse a literal-operator-id.
   //
-  //   literal-operator-id: [C++0x 13.5.8]
-  //     operator "" identifier
+  //   literal-operator-id: C++11 [over.literal]
+  //     operator string-literal identifier
+  //     operator user-defined-string-literal
 
   if (getLangOpts().CPlusPlus0x && isTokenStringLiteral()) {
     Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);
@@ -1896,6 +1897,9 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
     llvm::SmallVector<SourceLocation, 4> TokLocs;
     while (isTokenStringLiteral()) {
       if (!Tok.is(tok::string_literal) && !DiagId) {
+        // C++11 [over.literal]p1:
+        //   The string-literal or user-defined-string-literal in a
+        //   literal-operator-id shall have no encoding-prefix [...].
         DiagLoc = Tok.getLocation();
         DiagId = diag::err_literal_operator_string_prefix;
       }
@@ -1917,9 +1921,6 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
         Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()],
                                        Literal.getUDSuffixOffset(),
                                        PP.getSourceManager(), getLangOpts());
-      // This form is not permitted by the standard (yet).
-      DiagLoc = SuffixLoc;
-      DiagId = diag::err_literal_operator_missing_space;
     } else if (Tok.is(tok::identifier)) {
       II = Tok.getIdentifierInfo();
       SuffixLoc = ConsumeToken();
@@ -1931,6 +1932,10 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
 
     // The string literal must be empty.
     if (!Literal.GetString().empty() || Literal.Pascal) {
+      // C++11 [over.literal]p1:
+      //   The string-literal or user-defined-string-literal in a
+      //   literal-operator-id shall [...] contain no characters
+      //   other than the implicit terminating '\0'.
       DiagLoc = TokLocs.front();
       DiagId = diag::err_literal_operator_string_not_empty;
     }
index 3f76082..6f63610 100644 (file)
@@ -9,11 +9,10 @@ void operator "" _km(long double); // ok
 string operator "" _i18n(const char*, std::size_t); // ok
 // FIXME: This should be accepted once we support UCNs
 template<char...> int operator "" \u03C0(); // ok, UCN for lowercase pi // expected-error {{expected identifier}}
-float operator ""E(const char *); // expected-error {{C++11 requires a space between literal and identifier}} expected-warning {{reserved}}
+float operator ""E(const char *); // expected-error {{invalid suffix on literal}} expected-warning {{reserved}}
 float operator " " B(const char *); // expected-error {{must be '""'}} expected-warning {{reserved}}
 string operator "" 5X(const char *, std::size_t); // expected-error {{expected identifier}}
 double operator "" _miles(double); // expected-error {{parameter}}
 template<char...> int operator "" j(const char*); // expected-error {{parameter}}
 
-// FIXME: Accept this as an extension, with a fix-it to add the space
-float operator ""_E(const char *); // expected-error {{C++11 requires a space between the "" and the user-defined suffix in a literal operator}}
+float operator ""_E(const char *);
index 0c837b4..a173ce4 100644 (file)
@@ -66,13 +66,11 @@ const char *p = "foo"bar; // expected-error {{requires a space between}}
 #define ord - '0'
 int k = '4'ord; // expected-error {{requires a space between}}
 
-void operator""_x(char); // expected-error {{requires a space}}
 void operator"x" _y(char); // expected-error {{must be '""'}}
 void operator L"" _z(char); // expected-error {{encoding prefix}}
 void operator "x" "y" U"z" ""_whoops "z" "y"(char); // expected-error {{must be '""'}}
 
 void f() {
-  'a'_x;
   'b'_y;
   'c'_z;
   'd'_whoops;
index 49fea01..613c0b9 100644 (file)
@@ -102,9 +102,10 @@ void operator R"xyzzy()xyzzy" _foo(long double); // ok
 
 void operator"" "" R"()" "" _foo(const char *); // ok
 
+void operator ""_no_space(const char *); // ok
+
 // Ensure we diagnose the bad cases.
 void operator "\0" _non_empty(const char *); // expected-error {{must be '""'}}
-void operator ""_no_space(const char *); // expected-error {{C++11 requires a space}}
 void operator L"" _not_char(const char *); // expected-error {{cannot have an encoding prefix}}
 void operator "" ""
 U"" // expected-error {{cannot have an encoding prefix}}