aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYunzhong Gao <Yunzhong_Gao@playstation.sony.com>2014-04-11 20:55:19 +0000
committerYunzhong Gao <Yunzhong_Gao@playstation.sony.com>2014-04-11 20:55:19 +0000
commitbfd91e65a139a7c1357ba7105b2ebbabfc2a0192 (patch)
tree72044cbaa6771553e6e2350c3d85127c1fa1eb13
parenta00a56b905a1e6a1102f21fad0b4ca71e647d8b5 (diff)
downloadclang_35a-bfd91e65a139a7c1357ba7105b2ebbabfc2a0192.tar.gz
Add a test to distinguish between reserved tokens and normal identifiers.
The -fms-extensions option affects a number of subtle front-end C/C++ behaviors, and it would be useful to be able to distinguish MS keywords from regular identifiers in the ms-extensions mode even if the triple does not define a Windows target. It should make life easier if anyone needs to port their Windows codes to elsewhere. Differential Revision: http://reviews.llvm.org/D3034 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206069 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Lex/Preprocessor.h1
-rw-r--r--lib/Lex/PPMacroExpansion.cpp4
-rw-r--r--test/Lexer/keywords_test.c29
3 files changed, 34 insertions, 0 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 54dee61493..83af8fb3ca 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -125,6 +125,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
IdentifierInfo *Ident__has_include; // __has_include
IdentifierInfo *Ident__has_include_next; // __has_include_next
IdentifierInfo *Ident__has_warning; // __has_warning
+ IdentifierInfo *Ident__is_identifier; // __is_identifier
IdentifierInfo *Ident__building_module; // __building_module
IdentifierInfo *Ident__MODULE__; // __MODULE__
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 35f9192d38..76ab940db0 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -115,6 +115,7 @@ void Preprocessor::RegisterBuiltinMacros() {
Ident__has_include = RegisterBuiltinMacro(*this, "__has_include");
Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
Ident__has_warning = RegisterBuiltinMacro(*this, "__has_warning");
+ Ident__is_identifier = RegisterBuiltinMacro(*this, "__is_identifier");
// Modules.
if (LangOpts.Modules) {
@@ -1359,6 +1360,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
} else if (II == Ident__has_feature ||
II == Ident__has_extension ||
II == Ident__has_builtin ||
+ II == Ident__is_identifier ||
II == Ident__has_attribute) {
// The argument to these builtins should be a parenthesized identifier.
SourceLocation StartLoc = Tok.getLocation();
@@ -1382,6 +1384,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
bool Value = false;
if (!IsValid)
Diag(StartLoc, diag::err_feature_check_malformed);
+ else if (II == Ident__is_identifier)
+ Value = FeatureII->getTokenID() == tok::identifier;
else if (II == Ident__has_builtin) {
// Check for a builtin is trivial.
Value = FeatureII->getBuiltinID() != 0;
diff --git a/test/Lexer/keywords_test.c b/test/Lexer/keywords_test.c
new file mode 100644
index 0000000000..4eb1700e9b
--- /dev/null
+++ b/test/Lexer/keywords_test.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c99 -E %s -o - | FileCheck --check-prefix=CHECK-NONE %s
+
+// RUN: %clang_cc1 -std=gnu89 -E %s -o - \
+// RUN: | FileCheck --check-prefix=CHECK-GNU-KEYWORDS %s
+// RUN: %clang_cc1 -std=c99 -fgnu-keywords -E %s -o - \
+// RUN: | FileCheck --check-prefix=CHECK-GNU-KEYWORDS %s
+// RUN: %clang_cc1 -std=gnu89 -fno-gnu-keywords -E %s -o - \
+// RUN: | FileCheck --check-prefix=CHECK-NONE %s
+
+// RUN: %clang_cc1 -std=c99 -fms-extensions -E %s -o - \
+// RUN: | FileCheck --check-prefix=CHECK-MS-KEYWORDS %s
+
+void f() {
+// CHECK-NONE: int asm
+// CHECK-GNU-KEYWORDS: asm ("ret" : :)
+#if __is_identifier(asm)
+ int asm;
+#else
+ asm ("ret" : :);
+#endif
+}
+
+// CHECK-NONE: no_ms_wchar
+// CHECK-MS-KEYWORDS: has_ms_wchar
+#if __is_identifier(__wchar_t)
+void no_ms_wchar();
+#else
+void has_ms_wchar();
+#endif