arphaman updated this revision to Diff 126581.
arphaman added a comment.
Herald added a subscriber: javed.absar.

- Change error message.
- Take sub arch into account.


https://reviews.llvm.org/D41087

Files:
  include/clang/Lex/Preprocessor.h
  lib/Lex/PPMacroExpansion.cpp
  test/Preprocessor/is_target.c
  test/Preprocessor/is_target_arm.c
  test/Preprocessor/is_target_os_darwin.c
  test/Preprocessor/is_target_unknown.c

Index: test/Preprocessor/is_target_unknown.c
===================================================================
--- /dev/null
+++ test/Preprocessor/is_target_unknown.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -triple i686-unknown-unknown -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple i686-- -verify %s
+// expected-no-diagnostics
+
+#if __is_target_arch(unknown)
+  #error "mismatching arch"
+#endif
+
+// Unknown vendor is allowed.
+#if !__is_target_vendor(unknown)
+  #error "mismatching vendor"
+#endif
+
+// Unknown OS is allowed.
+#if !__is_target_os(unknown)
+  #error "mismatching OS"
+#endif
+
+// Unknown environment is allowed.
+#if !__is_target_environment(unknown)
+  #error "mismatching environment"
+#endif
Index: test/Preprocessor/is_target_os_darwin.c
===================================================================
--- /dev/null
+++ test/Preprocessor/is_target_os_darwin.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macos -DMAC -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-ios -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-tvos -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-watchos -verify %s
+// expected-no-diagnostics
+
+#if !__is_target_os(darwin)
+  #error "mismatching os"
+#endif
+
+// macOS matches both macOS and macOSX.
+#ifdef MAC
+
+#if !__is_target_os(macos)
+  #error "mismatching os"
+#endif
+
+#if !__is_target_os(macosx)
+  #error "mismatching os"
+#endif
+
+#if __is_target_os(ios)
+  #error "mismatching os"
+#endif
+
+#endif
Index: test/Preprocessor/is_target_arm.c
===================================================================
--- /dev/null
+++ test/Preprocessor/is_target_arm.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -triple thumbv7--windows-msvc19.11.0 -verify %s
+// expected-no-diagnostics
+
+// ARM does not match thumb.
+#if __is_target_arch(arm) || __is_target_arch(armv7)
+  #error "mismatching arch"
+#endif
+
+// Allow checking for precise arch + subarch.
+#if !__is_target_arch(thumbv7)
+  #error "mismatching arch"
+#endif
+
+// But also allow checking for the arch without subarch.
+#if !__is_target_arch(thumb)
+  #error "mismatching arch"
+#endif
+
+// Same arch with a different subarch doesn't match.
+#if __is_target_arch(thumbv6)
+  #error "mismatching arch"
+#endif
Index: test/Preprocessor/is_target.c
===================================================================
--- /dev/null
+++ test/Preprocessor/is_target.c
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin-simulator -verify %s
+
+#if !__is_target_arch(x86_64) || !__is_target_arch(X86_64)
+  #error "mismatching arch"
+#endif
+
+#if __is_target_arch(arm64)
+  #error "mismatching arch"
+#endif
+
+// Silently ignore invalid archs. This will ensure that older compilers will
+// accept headers that support new arches/vendors/os variants.
+#if __is_target_arch(foo)
+  #error "invalid arch"
+#endif
+
+#if !__is_target_vendor(apple) || !__is_target_vendor(APPLE)
+  #error "mismatching vendor"
+#endif
+
+#if __is_target_vendor(unknown)
+  #error "mismatching vendor"
+#endif
+
+#if __is_target_vendor(foo)
+  #error "invalid vendor"
+#endif
+
+#if !__is_target_os(darwin) || !__is_target_os(DARWIN)
+  #error "mismatching os"
+#endif
+
+#if __is_target_os(ios)
+  #error "mismatching os"
+#endif
+
+#if __is_target_os(foo)
+  #error "invalid os"
+#endif
+
+#if !__is_target_environment(simulator) || !__is_target_environment(SIMULATOR)
+  #error "mismatching environment"
+#endif
+
+#if __is_target_environment(unknown)
+  #error "mismatching environment"
+#endif
+
+#if __is_target_environment(foo)
+  #error "invalid environment"
+#endif
+
+#if !__has_builtin(__is_target_arch) || !__has_builtin(__is_target_os) || !__has_builtin(__is_target_vendor) || !__has_builtin(__is_target_environment)
+  #error "has builtin doesn't work"
+#endif
+
+#if __is_target_arch(11) // expected-error {{builtin feature check macro requires a parenthesized identifier}}
+  #error "invalid arch"
+#endif
+
+#if __is_target_arch x86 // expected-error{{missing '(' after '__is_target_arch'}}
+  #error "invalid arch"
+#endif
+
+#if __is_target_arch ( x86  // expected-error {{unterminated function-like macro invocation}}
+  #error "invalid arch"
+#endif // expected-error@-2 {{expected value in expression}}
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -375,6 +375,11 @@
   Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
   Ident__has_warning      = RegisterBuiltinMacro(*this, "__has_warning");
   Ident__is_identifier    = RegisterBuiltinMacro(*this, "__is_identifier");
+  Ident__is_target_arch   = RegisterBuiltinMacro(*this, "__is_target_arch");
+  Ident__is_target_vendor = RegisterBuiltinMacro(*this, "__is_target_vendor");
+  Ident__is_target_os     = RegisterBuiltinMacro(*this, "__is_target_os");
+  Ident__is_target_environment =
+      RegisterBuiltinMacro(*this, "__is_target_environment");
 
   // Modules.
   Ident__building_module  = RegisterBuiltinMacro(*this, "__building_module");
@@ -1755,6 +1760,10 @@
                       .Case("__make_integer_seq", LangOpts.CPlusPlus)
                       .Case("__type_pack_element", LangOpts.CPlusPlus)
                       .Case("__builtin_available", true)
+                      .Case("__is_target_arch", true)
+                      .Case("__is_target_vendor", true)
+                      .Case("__is_target_os", true)
+                      .Case("__is_target_environment", true)
                       .Default(false);
         }
       });
@@ -1906,6 +1915,60 @@
       Diag(LParenLoc, diag::note_matching) << tok::l_paren;
     }
     return;
+  } else if (II == Ident__is_target_arch) {
+    EvaluateFeatureLikeBuiltinMacro(
+        OS, Tok, II, *this, [this](Token &Tok, bool &HasLexedNextToken) -> int {
+          IdentifierInfo *II = ExpectFeatureIdentifierInfo(
+              Tok, *this, diag::err_feature_check_malformed);
+          if (!II)
+            return 0;
+          std::string ArchName = II->getName().lower() + "--";
+          llvm::Triple Arch(ArchName);
+          const llvm::Triple &Target = getTargetInfo().getTriple();
+          // Check the parsed arch when it has no sub arch to allow Clang to
+          // match thumb to thumbv7 but to prohibit matching thumbv6 to thumbv7.
+          return (Arch.getSubArch() == llvm::Triple::NoSubArch &&
+                  Arch.getArch() == Target.getArch()) ||
+                 Arch.getArchName() == Target.getArchName();
+        });
+  } else if (II == Ident__is_target_vendor) {
+    EvaluateFeatureLikeBuiltinMacro(
+        OS, Tok, II, *this, [this](Token &Tok, bool &HasLexedNextToken) -> int {
+          IdentifierInfo *II = ExpectFeatureIdentifierInfo(
+              Tok, *this, diag::err_feature_check_malformed);
+          StringRef VendorName = getTargetInfo().getTriple().getVendorName();
+          if (VendorName.empty())
+            VendorName = "unknown";
+          return II ? VendorName.equals_lower(II->getName()) : 0;
+        });
+  } else if (II == Ident__is_target_os) {
+    EvaluateFeatureLikeBuiltinMacro(
+        OS, Tok, II, *this, [this](Token &Tok, bool &HasLexedNextToken) -> int {
+          IdentifierInfo *II = ExpectFeatureIdentifierInfo(
+              Tok, *this, diag::err_feature_check_malformed);
+          if (!II)
+            return 0;
+          std::string OSName =
+              (llvm::Twine("unknown-unknown-") + II->getName().lower()).str();
+          llvm::Triple OS(OSName);
+          switch (OS.getOS()) {
+          case llvm::Triple::Darwin:
+            // Darwin matches macos, ios, etc.
+            return getTargetInfo().getTriple().isOSDarwin();
+          default:
+            return getTargetInfo().getTriple().getOS() == OS.getOS();
+          }
+        });
+  } else if (II == Ident__is_target_environment) {
+    EvaluateFeatureLikeBuiltinMacro(
+        OS, Tok, II, *this, [this](Token &Tok, bool &HasLexedNextToken) -> int {
+          IdentifierInfo *II = ExpectFeatureIdentifierInfo(
+              Tok, *this, diag::err_feature_check_malformed);
+          StringRef EnvName = getTargetInfo().getTriple().getEnvironmentName();
+          if (EnvName.empty())
+            EnvName = "unknown";
+          return II ? EnvName.equals_lower(II->getName()) : 0;
+        });
   } else {
     llvm_unreachable("Unknown identifier!");
   }
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h
+++ include/clang/Lex/Preprocessor.h
@@ -175,6 +175,10 @@
   IdentifierInfo *Ident__has_cpp_attribute;        // __has_cpp_attribute
   IdentifierInfo *Ident__has_c_attribute;          // __has_c_attribute
   IdentifierInfo *Ident__has_declspec;             // __has_declspec_attribute
+  IdentifierInfo *Ident__is_target_arch;           // __is_target_arch
+  IdentifierInfo *Ident__is_target_vendor;         // __is_target_vendor
+  IdentifierInfo *Ident__is_target_os;             // __is_target_os
+  IdentifierInfo *Ident__is_target_environment;    // __is_target_environment
 
   SourceLocation DATELoc, TIMELoc;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to