AntonBikineev updated the summary for this revision.
AntonBikineev updated this revision to Diff 78507.

https://reviews.llvm.org/D26829

Files:
  include/clang/Basic/DiagnosticLexKinds.td
  include/clang/Lex/LiteralSupport.h
  lib/Lex/Lexer.cpp
  lib/Lex/LiteralSupport.cpp

Index: lib/Lex/LiteralSupport.cpp
===================================================================
--- lib/Lex/LiteralSupport.cpp
+++ lib/Lex/LiteralSupport.cpp
@@ -1708,3 +1708,28 @@
 
   return SpellingPtr-SpellingStart;
 }
+
+/// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved
+/// suffixes as ud-suffixes, because the diagnostic experience is better if we
+/// treat it as an invalid suffix.
+StringLiteralParser::UDSuffixResult
+StringLiteralParser::isValidUDSuffix(const LangOptions &LangOpts,
+                                     StringRef Suffix) {
+  if (!LangOpts.CPlusPlus11 || Suffix.empty())
+    return UDSuffixResult::Invalid;
+
+  // By C++11 [lex.ext]p10, ud-suffixes starting with an '_' are always valid.
+  if (Suffix[0] == '_')
+    return UDSuffixResult::Valid;
+
+  // In C++11, there are no library suffixes.
+  if (!LangOpts.CPlusPlus14)
+    return UDSuffixResult::Invalid;
+
+  // C++1z adds "sv" literals
+  if (Suffix == "sv")
+    return LangOpts.CPlusPlus1z ? UDSuffixResult::Valid
+                                : UDSuffixResult::SVIncompatible;
+
+  return Suffix == "s" ? UDSuffixResult::Valid : UDSuffixResult::Invalid;
+}
Index: include/clang/Lex/LiteralSupport.h
===================================================================
--- include/clang/Lex/LiteralSupport.h
+++ include/clang/Lex/LiteralSupport.h
@@ -259,6 +259,13 @@
     return UDSuffixOffset;
   }
 
+  enum class UDSuffixResult : uint8_t {
+    Valid, Invalid, SVIncompatible
+  };
+
+  static UDSuffixResult isValidUDSuffix(const LangOptions &LangOpts,
+                                           StringRef Suffix);
+
 private:
   void init(ArrayRef<Token> StringToks);
   bool CopyStringFragment(const Token &Tok, const char *TokBegin,
Index: include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- include/clang/Basic/DiagnosticLexKinds.td
+++ include/clang/Basic/DiagnosticLexKinds.td
@@ -186,6 +186,8 @@
   "hexadecimal floating literals are incompatible with "
   "C++ standards before C++1z">,
   InGroup<CXXPre1zCompatPedantic>, DefaultIgnore;
+def err_cxx1z_string_view_literal : Error<
+  "string_view literals are a C++1z feature">;
 def ext_binary_literal : Extension<
   "binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>;
 def ext_binary_literal_cxx14 : Extension<
Index: lib/Lex/Lexer.cpp
===================================================================
--- lib/Lex/Lexer.cpp
+++ lib/Lex/Lexer.cpp
@@ -1697,6 +1697,8 @@
   // likely to be a ud-suffix than a macro, however, and accept that.
   if (!Consumed) {
     bool IsUDSuffix = false;
+    StringLiteralParser::UDSuffixResult IsStringUDSuffix =
+        StringLiteralParser::UDSuffixResult::Invalid;
     if (C == '_')
       IsUDSuffix = true;
     else if (IsStringLiteral && getLangOpts().CPlusPlus14) {
@@ -1713,9 +1715,18 @@
                                          getLangOpts());
         if (!isIdentifierBody(Next)) {
           // End of suffix. Check whether this is on the whitelist.
-          IsUDSuffix = (Chars == 1 && Buffer[0] == 's') ||
-                       NumericLiteralParser::isValidUDSuffix(
-                           getLangOpts(), StringRef(Buffer, Chars));
+          const StringRef CompleteSuffix = StringRef(Buffer, Chars);
+          const LangOptions &LangOpts = getLangOpts();
+          // First, check if the suffix is a numeric suffix (s,sv)
+          IsUDSuffix =
+              NumericLiteralParser::isValidUDSuffix(LangOpts, CompleteSuffix);
+          // If it is not, check for a string suffix
+          if (!IsUDSuffix) {
+            IsStringUDSuffix =
+                StringLiteralParser::isValidUDSuffix(LangOpts, CompleteSuffix);
+            IsUDSuffix =
+                IsStringUDSuffix == StringLiteralParser::UDSuffixResult::Valid;
+          }
           break;
         }
 
@@ -1730,10 +1741,16 @@
 
     if (!IsUDSuffix) {
       if (!isLexingRawMode())
-        Diag(CurPtr, getLangOpts().MSVCCompat
-                         ? diag::ext_ms_reserved_user_defined_literal
-                         : diag::ext_reserved_user_defined_literal)
-          << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
+        if (IsStringUDSuffix ==
+            StringLiteralParser::UDSuffixResult::SVIncompatible) {
+          Diag(CurPtr, diag::err_cxx1z_string_view_literal)
+            << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
+        } else {
+          Diag(CurPtr, getLangOpts().MSVCCompat
+                           ? diag::ext_ms_reserved_user_defined_literal
+                           : diag::ext_reserved_user_defined_literal)
+            << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
+        }
       return CurPtr;
     }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to