]> granicus.if.org Git - clang/commitdiff
Add a test to distinguish between reserved tokens and normal identifiers.
authorYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Fri, 11 Apr 2014 20:55:19 +0000 (20:55 +0000)
committerYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Fri, 11 Apr 2014 20:55:19 +0000 (20:55 +0000)
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

include/clang/Lex/Preprocessor.h
lib/Lex/PPMacroExpansion.cpp
test/Lexer/keywords_test.c [new file with mode: 0644]

index 54dee6149387cebfce0b15198389a177a4c16199..83af8fb3ca6afc6d4cd82a7070ad80c11226688c 100644 (file)
@@ -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__
 
index 35f9192d38ea1fa58eccc8eb34a9d2919cfe4c72..76ab940db0a660a5b580fa8fe95ba741c3b9f3cb 100644 (file)
@@ -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 (file)
index 0000000..4eb1700
--- /dev/null
@@ -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