Implement C++11 [lex.ext]p10 for string and character literals: a ud-suffix not
starting with an underscore is ill-formed.

Since this rule rejects programs that were using <inttypes.h>'s macros, recover
from this error by treating the ud-suffix as a separate preprocessing-token,
with a DefaultError ExtWarn. The approach of treating such cases as two tokens
is under discussion for standardization, but is in any case a conforming
extension and allows existing codebases to keep building while the committee
makes up its mind.

Reword the warning on the definition of literal operators not starting with
underscores (which are, strangely, legal) to more explicitly state that such
operators can't be called by literals. Remove the special-case diagnostic for
hexfloats, since it was both triggering in the wrong cases and incorrect.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152287 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index c40ff03..f5de122 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -79,7 +79,15 @@
 // Name of this warning in GCC
 def : DiagGroup<"narrowing", [CXX11Narrowing]>;
 
-def CXX11Compat : DiagGroup<"c++11-compat", [CXX11Narrowing]>;
+def CXX11CompatReservedUserDefinedLiteral :
+  DiagGroup<"c++11-compat-reserved-user-defined-literal">;
+def ReservedUserDefinedLiteral :
+  DiagGroup<"reserved-user-defined-literal",
+            [CXX11CompatReservedUserDefinedLiteral]>;
+
+def CXX11Compat : DiagGroup<"c++11-compat",
+                            [CXX11Narrowing,
+                             CXX11CompatReservedUserDefinedLiteral]>;
 def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
 
 def : DiagGroup<"effc++">;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index d31a48b..4fd55ef 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -134,6 +134,13 @@
 def warn_cxx11_compat_user_defined_literal : Warning<
   "identifier after literal will be treated as a user-defined literal suffix "
   "in C++11">, InGroup<CXX11Compat>, DefaultIgnore;
+def warn_cxx11_compat_reserved_user_defined_literal : Warning<
+  "identifier after literal will be treated as a reserved user-defined literal "
+  "suffix in C++11">,
+  InGroup<CXX11CompatReservedUserDefinedLiteral>, DefaultIgnore;
+def ext_reserved_user_defined_literal : ExtWarn<
+  "invalid suffix on literal; C++11 requires a space between literal and "
+  "identifier">, InGroup<ReservedUserDefinedLiteral>, DefaultError;
 def err_unsupported_string_concat : Error<
   "unsupported non-standard concatenation of string literals">;
 def err_string_concat_mixed_suffix : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 07a94be..0f5e767 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4757,13 +4757,11 @@
   "parameter declaration for literal operator %0 is not valid">;
 def err_literal_operator_extern_c : Error<
   "literal operator must have C++ linkage">;
-def warn_user_literal_hexfloat : Warning<
-  "user-defined literal with suffix '%0' is preempted by C99 hexfloat "
-  "extension">, InGroup<UserDefinedLiterals>;
 def warn_user_literal_reserved : Warning<
-  "user-defined literals not starting with '_' are reserved by the "
-  "implementation">, InGroup<UserDefinedLiterals>;
-  
+  "user-defined literal suffixes not starting with '_' are reserved; "
+  "no literal will invoke this operator">,
+  InGroup<UserDefinedLiterals>;
+
 // C++ conversion functions
 def err_conv_function_not_member : Error<
   "conversion function must be a non-static member function">;
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 0d388c6..0b34238 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1584,7 +1584,20 @@
   if (isIdentifierHead(C)) {
     if (!getFeatures().CPlusPlus0x) {
       if (!isLexingRawMode())
-        Diag(CurPtr, diag::warn_cxx11_compat_user_defined_literal)
+        Diag(CurPtr,
+             C == '_' ? diag::warn_cxx11_compat_user_defined_literal
+                      : diag::warn_cxx11_compat_reserved_user_defined_literal)
+          << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
+      return CurPtr;
+    }
+
+    // C++11 [lex.ext]p10, [usrlit.suffix]p1: A program containing a ud-suffix
+    // that does not start with an underscore is ill-formed. As a conforming
+    // extension, we treat all such suffixes as if they had whitespace before
+    // them.
+    if (C != '_') {
+      if (!isLexingRawMode())
+        Diag(CurPtr, diag::ext_reserved_user_defined_literal)
           << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
       return CurPtr;
     }
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index abcaf98..221cc6e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -9383,30 +9383,15 @@
     return true;
   }
 
-  StringRef LiteralName 
+  StringRef LiteralName
     = FnDecl->getDeclName().getCXXLiteralIdentifier()->getName();
   if (LiteralName[0] != '_') {
-    // C++0x [usrlit.suffix]p1:
-    //   Literal suffix identifiers that do not start with an underscore are 
-    //   reserved for future standardization.
-    bool IsHexFloat = true;
-    if (LiteralName.size() > 1 && 
-        (LiteralName[0] == 'P' || LiteralName[0] == 'p')) {
-      for (unsigned I = 1, N = LiteralName.size(); I < N; ++I) {
-        if (!isdigit(LiteralName[I])) {
-          IsHexFloat = false;
-          break;
-        }
-      }
-    }
-    
-    if (IsHexFloat)
-      Diag(FnDecl->getLocation(), diag::warn_user_literal_hexfloat)
-        << LiteralName;
-    else
-      Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved);
+    // C++11 [usrlit.suffix]p1:
+    //   Literal suffix identifiers that do not start with an underscore
+    //   are reserved for future standardization.
+    Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved);
   }
-  
+
   return false;
 }
 
diff --git a/test/CXX/lex/lex.literal/lex.ext/p1.cpp b/test/CXX/lex/lex.literal/lex.ext/p1.cpp
index c167e82..1c227a1 100644
--- a/test/CXX/lex/lex.literal/lex.ext/p1.cpp
+++ b/test/CXX/lex/lex.literal/lex.ext/p1.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 
-void operator "" p31(long double); // expected-warning{{user-defined literal with suffix 'p31' is preempted by C99 hexfloat extension}}
+void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
 void operator "" _p31(long double);
-long double operator "" pi(long double); // expected-warning{{user-defined literals not starting with '_' are reserved by the implementation}}
+long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
 
 float hexfloat = 0x1p31; // allow hexfloats
diff --git a/test/CXX/lex/lex.literal/lex.ext/p10.cpp b/test/CXX/lex/lex.literal/lex.ext/p10.cpp
index 6652c9a..dc86fdf 100644
--- a/test/CXX/lex/lex.literal/lex.ext/p10.cpp
+++ b/test/CXX/lex/lex.literal/lex.ext/p10.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 using size_t = decltype(sizeof(int));
-void operator "" wibble(const char *); // expected-warning {{preempted}}
-void operator "" wibble(const char *, size_t); // expected-warning {{preempted}}
+void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
 
 template<typename T>
 void f() {
@@ -10,6 +10,6 @@
   // FIXME: Reject these for the right reason.
   123wibble; // expected-error {{suffix 'wibble'}}
   123.0wibble; // expected-error {{suffix 'wibble'}}
-  ""wibble;
-  R"x("hello")x"wibble;
+  const char *p = ""wibble; // expected-error {{invalid suffix on literal; C++11 requires a space between literal and identifier}} expected-error {{expected ';'}}
+  const char *q = R"x("hello")x"wibble; // expected-error {{invalid suffix on literal; C++11 requires a space between literal and identifier}} expected-error {{expected ';'}}
 }
diff --git a/test/CXX/over/over.oper/over.literal/p8.cpp b/test/CXX/over/over.oper/over.literal/p8.cpp
index 1837aaf..3f76082 100644
--- a/test/CXX/over/over.oper/over.literal/p8.cpp
+++ b/test/CXX/over/over.oper/over.literal/p8.cpp
@@ -9,9 +9,11 @@
 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}}
-// 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 " " B(const char *); // expected-error {{must be '""'}} expected-warning {{hexfloat}}
+float operator ""E(const char *); // expected-error {{C++11 requires a space between literal and identifier}} 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}}
diff --git a/test/FixIt/fixit-cxx0x.cpp b/test/FixIt/fixit-cxx0x.cpp
index da6bf2f..2bf9b20 100644
--- a/test/FixIt/fixit-cxx0x.cpp
+++ b/test/FixIt/fixit-cxx0x.cpp
@@ -60,3 +60,8 @@
   (void)[] mutable { }; // expected-error{{lambda requires '()' before 'mutable'}}
   (void)[] -> int { }; // expected-error{{lambda requires '()' before return type}}
 }
+
+#define bar "bar"
+const char *p = "foo"bar; // expected-error {{requires a space between}}
+#define ord - '0'
+int k = '4'ord; // expected-error {{requires a space between}}
diff --git a/test/FixIt/fixit-cxx11-compat.cpp b/test/FixIt/fixit-cxx11-compat.cpp
index 3a5ec84..39ae439 100644
--- a/test/FixIt/fixit-cxx11-compat.cpp
+++ b/test/FixIt/fixit-cxx11-compat.cpp
@@ -6,4 +6,6 @@
 // This is a test of the code modification hints for C++11-compatibility problems.
 
 #define bar "bar"
-const char *p = "foo"bar; // expected-warning {{will be treated as a user-defined literal suffix}}
+const char *p = "foo"bar; // expected-warning {{will be treated as a reserved user-defined literal suffix}}
+#define _bar "_bar"
+const char *q = "foo"_bar; // expected-warning {{will be treated as a user-defined literal suffix}}
diff --git a/test/Parser/cxx0x-literal-operators.cpp b/test/Parser/cxx0x-literal-operators.cpp
index 4fcbad4..1881fcb 100644
--- a/test/Parser/cxx0x-literal-operators.cpp
+++ b/test/Parser/cxx0x-literal-operators.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
 void operator "" (const char *); // expected-error {{expected identifier}}
-void operator "k" foo(const char *); // expected-error {{string literal after 'operator' must be '""'}} \
-// expected-warning{{user-defined literal with suffix 'foo' is preempted by C99 hexfloat extension}}
-void operator "" tester (const char *); // expected-warning{{user-defined literal with suffix 'tester' is preempted by C99 hexfloat extension}}
+void operator "k" foo(const char *); // \
+  expected-error {{string literal after 'operator' must be '""'}} \
+  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" tester (const char *); // \
+  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp
index 611dcc7..123008a 100644
--- a/test/SemaCXX/cxx0x-compat.cpp
+++ b/test/SemaCXX/cxx0x-compat.cpp
@@ -32,8 +32,8 @@
 int printf(const char *, ...);
 typedef __typeof(sizeof(int)) size_t;
 void h(size_t foo, size_t bar) {
-  printf("foo is %"PRIuS", bar is %"PRIuS, foo, bar); // expected-warning 2{{identifier after literal will be treated as a user-defined literal suffix in C++11}}
+  printf("foo is %"PRIuS", bar is %"PRIuS, foo, bar); // expected-warning 2{{identifier after literal will be treated as a reserved user-defined literal suffix in C++11}}
 }
 
-#define x + 1
-char c = 'x'x; // expected-warning {{will be treated as a user-defined literal suffix}}
+#define _x + 1
+char c = 'x'_x; // expected-warning {{will be treated as a user-defined literal suffix}}