[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