Skip to content

Commit 11ba13a

Browse files
nicotru
authored andcommitted
[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
1 parent 80b4a25 commit 11ba13a

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

clang/include/clang/Lex/Preprocessor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ class Preprocessor {
178178
IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
179179
IdentifierInfo *Ident__is_target_os; // __is_target_os
180180
IdentifierInfo *Ident__is_target_environment; // __is_target_environment
181+
IdentifierInfo *Ident__is_target_variant_os;
182+
IdentifierInfo *Ident__is_target_variant_environment;
181183
IdentifierInfo *Ident__FLT_EVAL_METHOD__; // __FLT_EVAL_METHOD
182184

183185
// Weak, only valid (and set) while InMacroArgs is true.

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ void Preprocessor::RegisterBuiltinMacros() {
387387
Ident__is_target_os = RegisterBuiltinMacro(*this, "__is_target_os");
388388
Ident__is_target_environment =
389389
RegisterBuiltinMacro(*this, "__is_target_environment");
390+
Ident__is_target_variant_os =
391+
RegisterBuiltinMacro(*this, "__is_target_variant_os");
392+
Ident__is_target_variant_environment =
393+
RegisterBuiltinMacro(*this, "__is_target_variant_environment");
390394

391395
// Modules.
392396
Ident__building_module = RegisterBuiltinMacro(*this, "__building_module");
@@ -1431,6 +1435,39 @@ static bool isTargetEnvironment(const TargetInfo &TI,
14311435
return TI.getTriple().getEnvironment() == Env.getEnvironment();
14321436
}
14331437

1438+
/// Implements the __is_target_variant_os builtin macro.
1439+
static bool isTargetVariantOS(const TargetInfo &TI, const IdentifierInfo *II) {
1440+
if (TI.getTriple().isOSDarwin()) {
1441+
const llvm::Triple *VariantTriple = TI.getDarwinTargetVariantTriple();
1442+
if (!VariantTriple)
1443+
return false;
1444+
1445+
std::string OSName =
1446+
(llvm::Twine("unknown-unknown-") + II->getName().lower()).str();
1447+
llvm::Triple OS(OSName);
1448+
if (OS.getOS() == llvm::Triple::Darwin) {
1449+
// Darwin matches macos, ios, etc.
1450+
return VariantTriple->isOSDarwin();
1451+
}
1452+
return VariantTriple->getOS() == OS.getOS();
1453+
}
1454+
return false;
1455+
}
1456+
1457+
/// Implements the __is_target_variant_environment builtin macro.
1458+
static bool isTargetVariantEnvironment(const TargetInfo &TI,
1459+
const IdentifierInfo *II) {
1460+
if (TI.getTriple().isOSDarwin()) {
1461+
const llvm::Triple *VariantTriple = TI.getDarwinTargetVariantTriple();
1462+
if (!VariantTriple)
1463+
return false;
1464+
std::string EnvName = (llvm::Twine("---") + II->getName().lower()).str();
1465+
llvm::Triple Env(EnvName);
1466+
return VariantTriple->getEnvironment() == Env.getEnvironment();
1467+
}
1468+
return false;
1469+
}
1470+
14341471
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
14351472
/// as a builtin macro, handle it and return the next token as 'Tok'.
14361473
void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
@@ -1677,6 +1714,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
16771714
.Case("__is_target_vendor", true)
16781715
.Case("__is_target_os", true)
16791716
.Case("__is_target_environment", true)
1717+
.Case("__is_target_variant_os", true)
1718+
.Case("__is_target_variant_environment", true)
16801719
.Default(false);
16811720
}
16821721
});
@@ -1877,6 +1916,22 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
18771916
Tok, *this, diag::err_feature_check_malformed);
18781917
return II && isTargetEnvironment(getTargetInfo(), II);
18791918
});
1919+
} else if (II == Ident__is_target_variant_os) {
1920+
EvaluateFeatureLikeBuiltinMacro(
1921+
OS, Tok, II, *this, false,
1922+
[this](Token &Tok, bool &HasLexedNextToken) -> int {
1923+
IdentifierInfo *II = ExpectFeatureIdentifierInfo(
1924+
Tok, *this, diag::err_feature_check_malformed);
1925+
return II && isTargetVariantOS(getTargetInfo(), II);
1926+
});
1927+
} else if (II == Ident__is_target_variant_environment) {
1928+
EvaluateFeatureLikeBuiltinMacro(
1929+
OS, Tok, II, *this, false,
1930+
[this](Token &Tok, bool &HasLexedNextToken) -> int {
1931+
IdentifierInfo *II = ExpectFeatureIdentifierInfo(
1932+
Tok, *this, diag::err_feature_check_malformed);
1933+
return II && isTargetVariantEnvironment(getTargetInfo(), II);
1934+
});
18801935
} else {
18811936
llvm_unreachable("Unknown identifier!");
18821937
}

clang/test/Preprocessor/is_target_unknown.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,13 @@
2020
#if !__is_target_environment(unknown)
2121
#error "mismatching environment"
2222
#endif
23+
24+
// Unknown variant OS is not allowed.
25+
#if __is_target_variant_os(unknown)
26+
#error "mismatching OS"
27+
#endif
28+
29+
// Unknown variant environment is not allowed.
30+
#if __is_target_variant_environment(unknown)
31+
#error "mismatching environment"
32+
#endif
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-macos -DMAC -verify %s
2+
// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios13.1 -DIOS -verify %s
3+
// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-ios13.1-macabi -DCATALYST -verify %s
4+
// RUN: %clang_cc1 -fsyntax-only -triple arm64-apple-macos12 -darwin-target-variant-triple arm64-apple-ios-macabi -DZIPPERED -verify %s
5+
// expected-no-diagnostics
6+
7+
#if !__has_builtin(__is_target_variant_os) || !__has_builtin(__is_target_variant_environment)
8+
#error "has builtin doesn't work"
9+
#endif
10+
11+
#ifdef ZIPPERED
12+
13+
// Target variant is a darwin.
14+
#if !__is_target_variant_os(darwin)
15+
#error "mismatching variant os"
16+
#endif
17+
18+
// Target variant is not macOS...
19+
#if __is_target_variant_os(macos)
20+
#error "mismatching variant os"
21+
#endif
22+
23+
// ...but iOS.
24+
#if !__is_target_variant_os(ios)
25+
#error "mismatching variant os"
26+
#endif
27+
28+
// Zippered builds also set the target variant environment to macabi.
29+
// At the moment, only zippered builds set __is_target_variant_os(ios),
30+
// so checking __is_target_variant_environment() is currently redundant
31+
// with checking the former.
32+
#if !__is_target_variant_environment(macabi)
33+
#error "mismatching variant environment"
34+
#endif
35+
36+
#else
37+
38+
// In non-zippered builds, even for catalyst, no target variant is set.
39+
// So these are all false.
40+
41+
#if __is_target_variant_os(darwin)
42+
#error "mismatching variant os"
43+
#endif
44+
45+
#if __is_target_variant_os(macos)
46+
#error "mismatching variant os"
47+
#endif
48+
49+
#if __is_target_variant_os(ios)
50+
#error "mismatching variant os"
51+
#endif
52+
53+
#if __is_target_variant_environment(macabi)
54+
#error "mismatching variant environment"
55+
#endif
56+
57+
#endif
58+
59+
// The target environment in zippered builds is _not_ macabi.
60+
// The target environment is macabi only in catalyst builds.
61+
#ifdef CATALYST
62+
#if !__is_target_environment(macabi)
63+
#error "mismatching environment"
64+
#endif
65+
#if !__is_target_os(ios)
66+
#error "mismatching os"
67+
#endif
68+
#else
69+
#if __is_target_environment(macabi)
70+
#error "mismatching environment"
71+
#endif
72+
#endif

0 commit comments

Comments
 (0)