[llvm-branch-commits] [clang] 11ba13a - [clang] Add __is_target_variant_{os, environment} builtins

Tobias Hieta via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Sep 1 23:07:00 PDT 2022


Author: Nico Weber
Date: 2022-09-02T08:06:26+02:00
New Revision: 11ba13a625066a979b5c3d1039a1744d0d978c70

URL: https://github.com/llvm/llvm-project/commit/11ba13a625066a979b5c3d1039a1744d0d978c70
DIFF: https://github.com/llvm/llvm-project/commit/11ba13a625066a979b5c3d1039a1744d0d978c70.diff

LOG: [clang] Add __is_target_variant_{os,environment} builtins

Xcode 13's clang has them. For the included testcase, Xcode's clang
behaves like the implementation in this patch.

Availability.h in the macOS 12.0 SDK (part of Xcode 13, and the current
stable version of the macOS SDK) does something like:

   #if defined(__has_builtin)
     ...
     #if __has_builtin(__is_target_os)
      #if __has_builtin(__is_target_environment)
       #if __has_builtin(__is_target_variant_os)
        #if __has_builtin(__is_target_variant_environment)
         #if (... && ((__is_target_os(ios) && __is_target_environment(macabi)) || (__is_target_variant_os(ios) && __is_target_variant_environment(macabi))))
           #define __OSX_AVAILABLE_STARTING(_osx, _ios) ...
           #define __OSX_AVAILABLE_BUT_DEPRECATED(_osxIntro, _osxDep, _iosIntro, _iosDep) ...
           #define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osxIntro, _osxDep, _iosIntro, _iosDep, _msg) ...

So if __has_builtin(__is_target_variant_os) or
__has_builtin(__is_target_variant_environment) are false, these defines are not
defined.

Most of the time, this doesn't matter. But open-source clang currently fails
to commpile a file containing only `#include <Security/cssmtype.h>` when
building for catalyst by adding a `-target arm64-apple-ios13.1-macabi` triple,
due to those __OSX_AVAILABLE macros not being set correctly.

If a potential future SDK version were to include cssmtype.h transitively
from a common header such as `<Foundation/Foundation.h>`, then it would become
close to impossible to build Catalyst binaries with open-source clang.

To fix this for normal catalyst builds, it's only necessary that
__has_builtin() evaluates to true for these two built-ins -- the implementation
of them doesn't matter. But as a courtesy, a correct (at least on the test
cases I tried) implementation is provided. (This should also help people who
try to build zippered code, where having the correct implementation does
matter.)

Differential Revision: https://reviews.llvm.org/D132754

Added: 
    clang/test/Preprocessor/is_target_variant.c

Modified: 
    clang/include/clang/Lex/Preprocessor.h
    clang/lib/Lex/PPMacroExpansion.cpp
    clang/test/Preprocessor/is_target_unknown.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index bed486658ee09..7c5df05069edd 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -178,6 +178,8 @@ class Preprocessor {
   IdentifierInfo *Ident__is_target_vendor;         // __is_target_vendor
   IdentifierInfo *Ident__is_target_os;             // __is_target_os
   IdentifierInfo *Ident__is_target_environment;    // __is_target_environment
+  IdentifierInfo *Ident__is_target_variant_os;
+  IdentifierInfo *Ident__is_target_variant_environment;
   IdentifierInfo *Ident__FLT_EVAL_METHOD__;        // __FLT_EVAL_METHOD
 
   // Weak, only valid (and set) while InMacroArgs is true.

diff  --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index f3be2107f985f..c56f41c4495e6 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -387,6 +387,10 @@ void Preprocessor::RegisterBuiltinMacros() {
   Ident__is_target_os     = RegisterBuiltinMacro(*this, "__is_target_os");
   Ident__is_target_environment =
       RegisterBuiltinMacro(*this, "__is_target_environment");
+  Ident__is_target_variant_os =
+      RegisterBuiltinMacro(*this, "__is_target_variant_os");
+  Ident__is_target_variant_environment =
+      RegisterBuiltinMacro(*this, "__is_target_variant_environment");
 
   // Modules.
   Ident__building_module  = RegisterBuiltinMacro(*this, "__building_module");
@@ -1431,6 +1435,39 @@ static bool isTargetEnvironment(const TargetInfo &TI,
   return TI.getTriple().getEnvironment() == Env.getEnvironment();
 }
 
+/// Implements the __is_target_variant_os builtin macro.
+static bool isTargetVariantOS(const TargetInfo &TI, const IdentifierInfo *II) {
+  if (TI.getTriple().isOSDarwin()) {
+    const llvm::Triple *VariantTriple = TI.getDarwinTargetVariantTriple();
+    if (!VariantTriple)
+      return false;
+
+    std::string OSName =
+        (llvm::Twine("unknown-unknown-") + II->getName().lower()).str();
+    llvm::Triple OS(OSName);
+    if (OS.getOS() == llvm::Triple::Darwin) {
+      // Darwin matches macos, ios, etc.
+      return VariantTriple->isOSDarwin();
+    }
+    return VariantTriple->getOS() == OS.getOS();
+  }
+  return false;
+}
+
+/// Implements the __is_target_variant_environment builtin macro.
+static bool isTargetVariantEnvironment(const TargetInfo &TI,
+                                const IdentifierInfo *II) {
+  if (TI.getTriple().isOSDarwin()) {
+    const llvm::Triple *VariantTriple = TI.getDarwinTargetVariantTriple();
+    if (!VariantTriple)
+      return false;
+    std::string EnvName = (llvm::Twine("---") + II->getName().lower()).str();
+    llvm::Triple Env(EnvName);
+    return VariantTriple->getEnvironment() == Env.getEnvironment();
+  }
+  return false;
+}
+
 /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
 /// as a builtin macro, handle it and return the next token as 'Tok'.
 void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
@@ -1677,6 +1714,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
               .Case("__is_target_vendor", true)
               .Case("__is_target_os", true)
               .Case("__is_target_environment", true)
+              .Case("__is_target_variant_os", true)
+              .Case("__is_target_variant_environment", true)
               .Default(false);
         }
       });
@@ -1877,6 +1916,22 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
               Tok, *this, diag::err_feature_check_malformed);
           return II && isTargetEnvironment(getTargetInfo(), II);
         });
+  } else if (II == Ident__is_target_variant_os) {
+    EvaluateFeatureLikeBuiltinMacro(
+        OS, Tok, II, *this, false,
+        [this](Token &Tok, bool &HasLexedNextToken) -> int {
+          IdentifierInfo *II = ExpectFeatureIdentifierInfo(
+              Tok, *this, diag::err_feature_check_malformed);
+          return II && isTargetVariantOS(getTargetInfo(), II);
+        });
+  } else if (II == Ident__is_target_variant_environment) {
+    EvaluateFeatureLikeBuiltinMacro(
+        OS, Tok, II, *this, false,
+        [this](Token &Tok, bool &HasLexedNextToken) -> int {
+          IdentifierInfo *II = ExpectFeatureIdentifierInfo(
+              Tok, *this, diag::err_feature_check_malformed);
+          return II && isTargetVariantEnvironment(getTargetInfo(), II);
+        });
   } else {
     llvm_unreachable("Unknown identifier!");
   }

diff  --git a/clang/test/Preprocessor/is_target_unknown.c b/clang/test/Preprocessor/is_target_unknown.c
index d81afcbd22410..b61538fb39154 100644
--- a/clang/test/Preprocessor/is_target_unknown.c
+++ b/clang/test/Preprocessor/is_target_unknown.c
@@ -20,3 +20,13 @@
 #if !__is_target_environment(unknown)
   #error "mismatching environment"
 #endif
+
+// Unknown variant OS is not allowed.
+#if __is_target_variant_os(unknown)
+  #error "mismatching OS"
+#endif
+
+// Unknown variant environment is not allowed.
+#if __is_target_variant_environment(unknown)
+  #error "mismatching environment"
+#endif

diff  --git a/clang/test/Preprocessor/is_target_variant.c b/clang/test/Preprocessor/is_target_variant.c
new file mode 100644
index 0000000000000..8d374f878416c
--- /dev/null
+++ b/clang/test/Preprocessor/is_target_variant.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-macos -DMAC -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios13.1 -DIOS -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios13.1-macabi -DCATALYST -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-macos12 -darwin-target-variant-triple arm64-apple-ios-macabi -DZIPPERED -verify %s
+// expected-no-diagnostics
+
+#if !__has_builtin(__is_target_variant_os) || !__has_builtin(__is_target_variant_environment)
+  #error "has builtin doesn't work"
+#endif
+
+#ifdef ZIPPERED
+
+  // Target variant is a darwin.
+  #if !__is_target_variant_os(darwin)
+    #error "mismatching variant os"
+  #endif
+
+  // Target variant is not macOS...
+  #if __is_target_variant_os(macos)
+    #error "mismatching variant os"
+  #endif
+
+  // ...but iOS.
+  #if !__is_target_variant_os(ios)
+    #error "mismatching variant os"
+  #endif
+
+  // Zippered builds also set the target variant environment to macabi.
+  // At the moment, only zippered builds set __is_target_variant_os(ios),
+  // so checking __is_target_variant_environment() is currently redundant
+  // with checking the former.
+  #if !__is_target_variant_environment(macabi)
+    #error "mismatching variant environment"
+  #endif
+
+#else
+
+  // In non-zippered builds, even for catalyst, no target variant is set.
+  // So these are all false.
+
+  #if __is_target_variant_os(darwin)
+    #error "mismatching variant os"
+  #endif
+
+  #if __is_target_variant_os(macos)
+    #error "mismatching variant os"
+  #endif
+
+  #if __is_target_variant_os(ios)
+    #error "mismatching variant os"
+  #endif
+
+  #if __is_target_variant_environment(macabi)
+    #error "mismatching variant environment"
+  #endif
+
+#endif
+
+// The target environment in zippered builds is _not_ macabi.
+// The target environment is macabi only in catalyst builds.
+#ifdef CATALYST
+  #if !__is_target_environment(macabi)
+    #error "mismatching environment"
+  #endif
+  #if !__is_target_os(ios)
+    #error "mismatching os"
+  #endif
+#else
+  #if __is_target_environment(macabi)
+    #error "mismatching environment"
+  #endif
+#endif


        


More information about the llvm-branch-commits mailing list