AntonBikineev updated this revision to Diff 78510.
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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits