r337454 - Enable C++2a Chrono Literals

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 19 06:36:57 PDT 2018


Author: erichkeane
Date: Thu Jul 19 06:36:57 2018
New Revision: 337454

URL: http://llvm.org/viewvc/llvm-project?rev=337454&view=rev
Log:
Enable C++2a Chrono Literals

C++2a via http://wg21.link/p0355 permits the library
literals of 'd' and 'y'. This patch enables them in the
Lexer so that they can be properly parsed.

Note that 'd' gets confused with the hex character, so
modifications to how octal, binary, and decimal numbers are
parsed were required. Since this is simply making previously
invalid code legal, this should be fine.

Hex still greedily parses the 'd' as a hexit, since it would
a: violate [lex.ext]p1
b: break existing code.

Differential Revision: https://reviews.llvm.org/D49504

Added:
    cfe/trunk/test/SemaCXX/cxx2a-user-defined-literals.cpp
Modified:
    cfe/trunk/lib/Lex/LiteralSupport.cpp

Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=337454&r1=337453&r2=337454&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/trunk/lib/Lex/LiteralSupport.cpp Thu Jul 19 06:36:57 2018
@@ -751,7 +751,8 @@ void NumericLiteralParser::ParseDecimalO
 
   // If we have a hex digit other than 'e' (which denotes a FP exponent) then
   // the code is using an incorrect base.
-  if (isHexDigit(*s) && *s != 'e' && *s != 'E') {
+  if (isHexDigit(*s) && *s != 'e' && *s != 'E' &&
+      !isValidUDSuffix(PP.getLangOpts(), StringRef(s, ThisTokEnd - s))) {
     PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
             diag::err_invalid_digit) << StringRef(s, 1) << (radix == 8 ? 1 : 0);
     hadError = true;
@@ -804,12 +805,14 @@ bool NumericLiteralParser::isValidUDSuff
   if (!LangOpts.CPlusPlus14)
     return false;
 
-  // In C++1y, "s", "h", "min", "ms", "us", and "ns" are used in the library.
+  // In C++14, "s", "h", "min", "ms", "us", and "ns" are used in the library.
   // Per tweaked N3660, "il", "i", and "if" are also used in the library.
+  // In C++2a "d" and "y" are used in the library.
   return llvm::StringSwitch<bool>(Suffix)
       .Cases("h", "min", "s", true)
       .Cases("ms", "us", "ns", true)
       .Cases("il", "i", "if", true)
+      .Cases("d", "y", LangOpts.CPlusPlus2a)
       .Default(false);
 }
 
@@ -922,7 +925,9 @@ void NumericLiteralParser::ParseNumberSt
     s = SkipBinaryDigits(s);
     if (s == ThisTokEnd) {
       // Done.
-    } else if (isHexDigit(*s)) {
+    } else if (isHexDigit(*s) &&
+               !isValidUDSuffix(PP.getLangOpts(),
+                                StringRef(s, ThisTokEnd - s))) {
       PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
               diag::err_invalid_digit) << StringRef(s, 1) << 2;
       hadError = true;

Added: cfe/trunk/test/SemaCXX/cxx2a-user-defined-literals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-user-defined-literals.cpp?rev=337454&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx2a-user-defined-literals.cpp (added)
+++ cfe/trunk/test/SemaCXX/cxx2a-user-defined-literals.cpp Thu Jul 19 06:36:57 2018
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++2a %s -include %s -verify
+
+#ifndef INCLUDED
+#define INCLUDED
+
+#pragma clang system_header
+namespace std {
+  namespace chrono {
+    struct day{};
+    struct year{};
+  }
+  constexpr chrono::day operator"" d(unsigned long long d) noexcept;
+  constexpr chrono::year operator"" y(unsigned long long y) noexcept;
+}
+
+#else
+
+using namespace std;
+chrono::day dec_d = 5d;
+chrono::day oct_d = 05d;
+chrono::day bin_d = 0b011d;
+// expected-error at +3{{no viable conversion from 'int' to 'chrono::day'}}
+// expected-note at 9{{candidate constructor (the implicit copy constructor)}}
+// expected-note at 9{{candidate constructor (the implicit move constructor)}}
+chrono::day hex_d = 0x44d;
+chrono::year y  = 10y;
+#endif




More information about the cfe-commits mailing list