[cfe-commits] r138839 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticLexKinds.td include/clang/Basic/DiagnosticSemaKinds.td lib/Lex/LiteralSupport.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/lex/lex.literal/lex.ext/p1.cpp test/Parser/cxx0x-literal-operators.cpp test/SemaCXX/literal-operators.cpp

Douglas Gregor dgregor at apple.com
Tue Aug 30 15:40:35 PDT 2011


Author: dgregor
Date: Tue Aug 30 17:40:35 2011
New Revision: 138839

URL: http://llvm.org/viewvc/llvm-project?rev=138839&view=rev
Log:
Allow C99 hexfloats in C++0x mode. This change resolves the standards
collision between C99 hexfloats and C++0x user-defined literals by
giving C99 hexfloats precedence. Also, warning about user-defined
literals that conflict with hexfloats and those that have names that
are reserved by the implementation. Fixes <rdar://problem/9940194>.

Added:
    cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Lex/LiteralSupport.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/Parser/cxx0x-literal-operators.cpp
    cfe/trunk/test/SemaCXX/literal-operators.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=138839&r1=138838&r2=138839&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Aug 30 17:40:35 2011
@@ -54,10 +54,9 @@
 def FormatExtraArgs : DiagGroup<"format-extra-args">;
 def FormatZeroLength : DiagGroup<"format-zero-length">;
 
-def CXXHexFloats : DiagGroup<"c++-hex-floats">;
 def CXX0xNarrowing : DiagGroup<"c++0x-narrowing">;
 
-def CXX0xCompat : DiagGroup<"c++0x-compat", [CXXHexFloats, CXX0xNarrowing]>;
+def CXX0xCompat : DiagGroup<"c++0x-compat", [CXX0xNarrowing]>;
 def : DiagGroup<"effc++">;
 def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
 def FourByteMultiChar : DiagGroup<"four-char-constants">;
@@ -169,6 +168,7 @@
 def UnusedValue : DiagGroup<"unused-value", [UnusedComparison, UnusedResult]>;
 def UnusedVariable : DiagGroup<"unused-variable">;
 def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
+def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
 def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
 def Reorder : DiagGroup<"reorder">;
 def UndeclaredSelector : DiagGroup<"undeclared-selector">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=138839&r1=138838&r2=138839&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Tue Aug 30 17:40:35 2011
@@ -94,9 +94,6 @@
 def ext_imaginary_constant : Extension<"imaginary constants are an extension">;
 def err_hexconstant_requires_exponent : Error<
   "hexadecimal floating constants require an exponent">;
-def ext_hexconstant_cplusplus : Extension<
-  "hexadecimal floating constants are a C99 feature that is incompatible with "
-  "C++0x">, InGroup<CXXHexFloats>;
 def ext_hexconstant_invalid : Extension<
   "hexadecimal floating constants are a C99 feature">;
 def ext_binary_literal : Extension<

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=138839&r1=138838&r2=138839&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 30 17:40:35 2011
@@ -4152,7 +4152,13 @@
 // FIXME: This diagnostic sucks
 def err_literal_operator_params : Error<
   "parameter declaration for literal operator %0 is not valid">;
-
+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>;
+  
 // C++ conversion functions
 def err_conv_function_not_member : Error<
   "conversion function must be a non-static member function">;

Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=138839&r1=138838&r2=138839&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/trunk/lib/Lex/LiteralSupport.cpp Tue Aug 30 17:40:35 2011
@@ -546,7 +546,7 @@
     }
     // A binary exponent can appear with or with a '.'. If dotted, the
     // binary exponent is required.
-    if ((*s == 'p' || *s == 'P') && !PP.getLangOptions().CPlusPlus0x) {
+    if (*s == 'p' || *s == 'P') {
       const char *Exponent = s;
       s++;
       saw_exponent = true;
@@ -563,9 +563,7 @@
       // In C++0x, we cannot support hexadecmial floating literals because
       // they conflict with user-defined literals, so we warn in previous
       // versions of C++ by default.
-      if (PP.getLangOptions().CPlusPlus)
-        PP.Diag(TokLoc, diag::ext_hexconstant_cplusplus);
-      else if (!PP.getLangOptions().HexFloats)
+      if (!PP.getLangOptions().HexFloats)
         PP.Diag(TokLoc, diag::ext_hexconstant_invalid);
     } else if (saw_period) {
       PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=138839&r1=138838&r2=138839&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Aug 30 17:40:35 2011
@@ -9048,6 +9048,30 @@
     return true;
   }
 
+  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);
+  }
+  
   return false;
 }
 

Added: cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp?rev=138839&view=auto
==============================================================================
--- cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp (added)
+++ cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp Tue Aug 30 17:40:35 2011
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+int * operator "" p31(long double); // expected-warning{{user-defined literal with suffix 'p31' is preempted by C99 hexfloat extension}}
+long double operator "" _p31(long double);
+long double operator "" pi(long double); // expected-warning{{user-defined literals not starting with '_' are reserved by the implementation}}
+
+float hexfloat = 0x1p31; // allow hexfloats

Modified: cfe/trunk/test/Parser/cxx0x-literal-operators.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-literal-operators.cpp?rev=138839&r1=138838&r2=138839&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-literal-operators.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-literal-operators.cpp Tue Aug 30 17:40:35 2011
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
 
 void operator "" (const char *); // expected-error {{expected identifier}}
-void operator "k" foo(const char *); // expected-error {{string literal after 'operator' must be '""'}}
-void operator "" tester (const char *);
+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}}

Modified: cfe/trunk/test/SemaCXX/literal-operators.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/literal-operators.cpp?rev=138839&r1=138838&r2=138839&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/literal-operators.cpp (original)
+++ cfe/trunk/test/SemaCXX/literal-operators.cpp Tue Aug 30 17:40:35 2011
@@ -3,39 +3,39 @@
 #include <stddef.h>
 
 struct tag {
-  void operator "" tag_bad (const char *); // expected-error {{literal operator 'operator "" tag_bad' must be in a namespace or global scope}}
-  friend void operator "" tag_good (const char *);
+  void operator "" _tag_bad (const char *); // expected-error {{literal operator 'operator "" _tag_bad' must be in a namespace or global scope}}
+  friend void operator "" _tag_good (const char *);
 };
 
-namespace ns { void operator "" ns_good (const char *); }
+namespace ns { void operator "" _ns_good (const char *); }
 
 // Check extern "C++" declarations
-extern "C++" void operator "" extern_good (const char *);
-extern "C++" { void operator "" extern_good (const char *); }
+extern "C++" void operator "" _extern_good (const char *);
+extern "C++" { void operator "" _extern_good (const char *); }
 
-void fn () { void operator "" fn_bad (const char *); } // expected-error {{literal operator 'operator "" fn_bad' must be in a namespace or global scope}}
+void fn () { void operator "" _fn_bad (const char *); } // expected-error {{literal operator 'operator "" _fn_bad' must be in a namespace or global scope}}
 
 // One-param declarations (const char * was already checked)
-void operator "" good (char);
-void operator "" good (wchar_t);
-void operator "" good (char16_t);
-void operator "" good (char32_t);
-void operator "" good (unsigned long long);
-void operator "" good (long double);
+void operator "" _good (char);
+void operator "" _good (wchar_t);
+void operator "" _good (char16_t);
+void operator "" _good (char32_t);
+void operator "" _good (unsigned long long);
+void operator "" _good (long double);
 
 // Two-param declarations
-void operator "" good (const char *, size_t);
-void operator "" good (const wchar_t *, size_t);
-void operator "" good (const char16_t *, size_t);
-void operator "" good (const char32_t *, size_t);
+void operator "" _good (const char *, size_t);
+void operator "" _good (const wchar_t *, size_t);
+void operator "" _good (const char16_t *, size_t);
+void operator "" _good (const char32_t *, size_t);
 
 // Check typedef and array equivalences
-void operator "" good (const char[]);
+void operator "" _good (const char[]);
 typedef const char c;
-void operator "" good (c*);
+void operator "" _good (c*);
 
 // Check extra cv-qualifiers
-void operator "" cv_good (volatile const char *, const size_t);
+void operator "" _cv_good (volatile const char *, const size_t);
 
 // Template delcaration (not implemented yet)
 // template <char...> void operator "" good ();





More information about the cfe-commits mailing list