From 904c87881414c4e06bf4254cacebd372b3f4c952 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Fri, 30 Dec 2016 04:51:10 +0000 Subject: [PATCH] Allow lexer to handle string_view literals. Patch from Anton Bikineev. This implements the compiler side of p0403r0. This patch was reviewed as https://reviews.llvm.org/D26829. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290744 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/LiteralSupport.h | 2 ++ lib/Lex/Lexer.cpp | 6 +++--- lib/Lex/LiteralSupport.cpp | 9 +++++++++ lib/Sema/SemaDeclCXX.cpp | 2 +- test/SemaCXX/cxx1z-user-defined-literals.cpp | 21 ++++++++++++++++++++ 5 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 test/SemaCXX/cxx1z-user-defined-literals.cpp diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index 5f946fc833..b66581b428 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -259,6 +259,8 @@ public: return UDSuffixOffset; } + static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix); + private: void init(ArrayRef StringToks); bool CopyStringFragment(const Token &Tok, const char *TokBegin, diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 37c7aa4c57..6025a66751 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -1713,9 +1713,9 @@ const char *Lexer::LexUDSuffix(Token &Result, const char *CurPtr, 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(Buffer, Chars); + IsUDSuffix = StringLiteralParser::isValidUDSuffix(getLangOpts(), + CompleteSuffix); break; } diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index 582ed3ff47..fbfd3fe5cc 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -1708,3 +1708,12 @@ unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok, 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. +bool StringLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, + StringRef Suffix) { + return NumericLiteralParser::isValidUDSuffix(LangOpts, Suffix) || + Suffix == "sv"; +} diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 21bdd945f0..084bd4c45e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -12913,7 +12913,7 @@ bool Sema::CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl) { // Literal suffix identifiers that do not start with an underscore // are reserved for future standardization. Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved) - << NumericLiteralParser::isValidUDSuffix(getLangOpts(), LiteralName); + << StringLiteralParser::isValidUDSuffix(getLangOpts(), LiteralName); } return false; diff --git a/test/SemaCXX/cxx1z-user-defined-literals.cpp b/test/SemaCXX/cxx1z-user-defined-literals.cpp new file mode 100644 index 0000000000..978fd2fbc4 --- /dev/null +++ b/test/SemaCXX/cxx1z-user-defined-literals.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++1z %s -include %s -verify + +#ifndef INCLUDED +#define INCLUDED + +#pragma clang system_header +namespace std { + using size_t = decltype(sizeof(0)); + + struct string_view {}; + string_view operator""sv(const char*, size_t); +} + +#else + +using namespace std; +string_view s = "foo"sv; +const char* p = "bar"sv; // expected-error {{no viable conversion}} +char error = 'x'sv; // expected-error {{invalid suffix}} expected-error {{expected ';'}} + +#endif -- 2.40.0