[cfe-commits] r141700 - in /cfe/trunk: include/clang/Basic/DiagnosticLexKinds.td include/clang/Basic/IdentifierTable.h include/clang/Lex/Preprocessor.h lib/Basic/IdentifierTable.cpp lib/Lex/Preprocessor.cpp test/Lexer/cxx0x_keyword_as_cxx98.cpp test/SemaCXX/decltype-crash.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Tue Oct 11 12:57:52 PDT 2011
Author: rsmith
Date: Tue Oct 11 14:57:52 2011
New Revision: 141700
URL: http://llvm.org/viewvc/llvm-project?rev=141700&view=rev
Log:
Add a -Wc++0x-compat warning for C++11 keywords used as identifiers when in
C++98 mode. Only the first occurrence of each keyword will produce a warning.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/include/clang/Basic/IdentifierTable.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Basic/IdentifierTable.cpp
cfe/trunk/lib/Lex/Preprocessor.cpp
cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp
cfe/trunk/test/SemaCXX/decltype-crash.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Tue Oct 11 14:57:52 2011
@@ -46,6 +46,9 @@
def ext_token_used : Extension<"extension used">,
InGroup<DiagGroup<"language-extension-token">>;
+def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
+ InGroup<CXX0xCompat>;
+
def warn_unterminated_string : ExtWarn<"missing terminating '\"' character">;
def warn_unterminated_char : ExtWarn<"missing terminating ' character">;
def err_empty_character : Error<"empty character constant">;
Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Tue Oct 11 14:57:52 2011
@@ -58,6 +58,7 @@
unsigned ObjCOrBuiltinID :11;
bool HasMacro : 1; // True if there is a #define for this.
bool IsExtension : 1; // True if identifier is a lang extension.
+ bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11.
bool IsPoisoned : 1; // True if identifier is poisoned.
bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier".
@@ -199,6 +200,19 @@
RecomputeNeedsHandleIdentifier();
}
+ /// is/setIsCXX11CompatKeyword - Initialize information about whether or not
+ /// this language token is a keyword in C++11. This controls compatibility
+ /// warnings, and is only true when not parsing C++11. Once a compatibility
+ /// problem has been diagnosed with this keyword, the flag will be cleared.
+ bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; }
+ void setIsCXX11CompatKeyword(bool Val) {
+ IsCXX11CompatKeyword = Val;
+ if (Val)
+ NeedsHandleIdentifier = 1;
+ else
+ RecomputeNeedsHandleIdentifier();
+ }
+
/// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
/// Preprocessor will emit an error every time this token is used.
void setIsPoisoned(bool Value = true) {
@@ -252,7 +266,8 @@
void RecomputeNeedsHandleIdentifier() {
NeedsHandleIdentifier =
(isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
- isExtensionToken() || (getTokenID() == tok::kw___import_module__));
+ isExtensionToken() | isCXX11CompatKeyword() ||
+ (getTokenID() == tok::kw___import_module__));
}
};
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Oct 11 14:57:52 2011
@@ -752,11 +752,11 @@
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
/// the specified Token's location, translating the token's start
/// position in the current buffer into a SourcePosition object for rendering.
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+ DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
return Diags->Report(Loc, DiagID);
}
- DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) {
+ DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const {
return Diags->Report(Tok.getLocation(), DiagID);
}
Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Tue Oct 11 14:57:52 2011
@@ -32,6 +32,7 @@
ObjCOrBuiltinID = 0;
HasMacro = false;
IsExtension = false;
+ IsCXX11CompatKeyword = false;
IsPoisoned = false;
IsCPPOperatorKeyword = false;
NeedsHandleIdentifier = false;
@@ -102,10 +103,10 @@
/// identifiers because they are language keywords. This causes the lexer to
/// automatically map matching identifiers to specialized token codes.
///
-/// The C90/C99/CPP/CPP0x flags are set to 2 if the token should be
-/// enabled in the specified langauge, set to 1 if it is an extension
-/// in the specified language, and set to 0 if disabled in the
-/// specified language.
+/// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a
+/// future language standard, set to 2 if the token should be enabled in the
+/// specified langauge, set to 1 if it is an extension in the specified
+/// language, and set to 0 if disabled in the specified language.
static void AddKeyword(StringRef Keyword,
tok::TokenKind TokenCode, unsigned Flags,
const LangOptions &LangOpts, IdentifierTable &Table) {
@@ -123,12 +124,15 @@
else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2;
else if (LangOpts.C1X && (Flags & KEYC1X)) AddResult = 2;
else if (LangOpts.ObjCAutoRefCount && (Flags & KEYARC)) AddResult = 2;
-
+ else if (LangOpts.CPlusPlus && (Flags & KEYCXX0X)) AddResult = 3;
+
// Don't add this keyword if disabled in this language.
if (AddResult == 0) return;
- IdentifierInfo &Info = Table.get(Keyword, TokenCode);
+ IdentifierInfo &Info =
+ Table.get(Keyword, AddResult == 3 ? tok::identifier : TokenCode);
Info.setIsExtensionToken(AddResult == 1);
+ Info.setIsCXX11CompatKeyword(AddResult == 3);
}
/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
@@ -493,4 +497,3 @@
return 0;
}
-
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Oct 11 14:57:52 2011
@@ -513,6 +513,17 @@
}
}
+ // If this identifier is a keyword in C++11, produce a warning. Don't warn if
+ // we're not considering macro expansion, since this identifier might be the
+ // name of a macro.
+ // FIXME: This warning is disabled in cases where it shouldn't be, like
+ // "#define constexpr constexpr", "int constexpr;"
+ if (II.isCXX11CompatKeyword() & !DisableMacroExpansion) {
+ Diag(Identifier, diag::warn_cxx11_keyword) << II.getName();
+ // Don't diagnose this keyword again in this translation unit.
+ II.setIsCXX11CompatKeyword(false);
+ }
+
// C++ 2.11p2: If this is an alternative representation of a C++ operator,
// then we act as if it is the actual operator and not the textual
// representation of it.
Modified: cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp (original)
+++ cfe/trunk/test/Lexer/cxx0x_keyword_as_cxx98.cpp Tue Oct 11 14:57:52 2011
@@ -1,3 +1,36 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
-int static_assert;
-int char16_t;
+
+#define thread_local __thread
+thread_local int x;
+#undef thread_local
+
+namespace lib {
+ struct nullptr_t;
+ typedef nullptr_t nullptr; // expected-warning {{'nullptr' is a keyword in C++11}}
+}
+
+#define CONCAT(X,Y) CONCAT2(X,Y)
+#define CONCAT2(X,Y) X ## Y
+int CONCAT(constexpr,ession);
+
+#define ID(X) X
+extern int ID(decltype); // expected-warning {{'decltype' is a keyword in C++11}}
+
+extern int CONCAT(align,of); // expected-warning {{'alignof' is a keyword in C++11}}
+
+#define static_assert(b, s) int CONCAT(check, __LINE__)[(b) ? 1 : 0];
+static_assert(1 > 0, "hello"); // ok
+
+#define IF_CXX11(CXX11, CXX03) CXX03
+typedef IF_CXX11(char16_t, wchar_t) my_wide_char_t; // ok
+
+int alignas; // expected-warning {{'alignas' is a keyword in C++11}}
+int alignof; // already diagnosed in this TU
+int char16_t; // expected-warning {{'char16_t' is a keyword in C++11}}
+int char32_t; // expected-warning {{'char32_t' is a keyword in C++11}}
+int constexpr; // expected-warning {{'constexpr' is a keyword in C++11}}
+int decltype; // already diagnosed in this TU
+int noexcept; // expected-warning {{'noexcept' is a keyword in C++11}}
+int nullptr; // already diagnosed in this TU
+int static_assert; // expected-warning {{'static_assert' is a keyword in C++11}}
+int thread_local; // expected-warning {{'thread_local' is a keyword in C++11}}
Modified: cfe/trunk/test/SemaCXX/decltype-crash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decltype-crash.cpp?rev=141700&r1=141699&r2=141700&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decltype-crash.cpp (original)
+++ cfe/trunk/test/SemaCXX/decltype-crash.cpp Tue Oct 11 14:57:52 2011
@@ -3,5 +3,5 @@
int& a();
void f() {
- decltype(a()) c; // expected-error {{use of undeclared identifier 'decltype'}}
+ decltype(a()) c; // expected-warning {{'decltype' is a keyword in C++11}} expected-error {{use of undeclared identifier 'decltype'}}
}
More information about the cfe-commits
mailing list