forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 353
Open
Description
The following snippet of Objective-C code, which declares the typedef as available on watchOS, and unavailable on iOS, macOS and tvOS platforms:
#import <Foundation/Foundation.h>
API_UNAVAILABLE(visionos) @interface Foo
@end
typedef void(^Bar)(Foo *foo) API_AVAILABLE(watchos(5.0)) API_UNAVAILABLE(ios,macos,tvos);Given iOS is unavailable, it also includes derivatives, which means visionOS.
Compiling this snippet with Apple's clang compiler works as expected:
echo "#import <Foundation/Foundation.h>\nAPI_UNAVAILABLE(visionos) @interface Foo\n@end\n typedef void(^Bar)(Foo *foo) API_AVAILABLE(watchos(5.0)) API_UNAVAILABLE(ios,macos,tvos);" | xcrun -sdk xros clang -mtargetos=xros2.5 -O2 -x objective-c -c -o test.o -
However, compiling with clang from here fails:
echo -e "#import <Foundation/Foundation.h>\nAPI_UNAVAILABLE(visionos) @interface Foo\n@end\ntypedef void(^Bar)(Foo *foo) API_AVAILABLE(watchos(5.0)) API_UNAVAILABLE(ios,macos,tvos);" | arm-apple-darwin11-clang -isysroot /root/SDKs/XROS2.5.sdk/ -mtargetos=xros2.5 -O2 -x objective-c -c -o test.o -
Output:
<stdin>:4:20: error: 'Foo' is unavailable: not available on visionOS
4 | typedef void(^Bar)(Foo *foo) API_AVAILABLE(watchos(5.0)) API_UNAVAILABLE(ios,macos,tvos);
| ^ <stdin>:2:38: note: 'Foo' has been explicitly marked unavailable here 2 | API_UNAVAILABLE(visionos) @interface Foo
| ^
1 error generated.
If I explicitly add visionos to the typedef declaration, it passes.
Unfortunately, this problem occurs when compiling Apple's SDKs, such as CoreMotion with llvm / clang, that has declarations such as:
/*!
* @typedef CMDyskineticSymptomResultHandler
* @brief Completion handler for CMDyskineticSymptomResult values.
*/
typedef void(^CMDyskineticSymptomResultHandler)(NSArray<CMDyskineticSymptomResult *> * _Nonnull dyskineticSymptomResult, NSError * _Nullable error) API_AVAILABLE(watchos(5.0)) API_UNAVAILABLE(ios, macos, tvos);Note
This is a copy of llvm#142502, as I realise I am using a build from the Apple fork of llvm via https://github.com/tpoechtrager/osxcross.
Patch to fix release/19.x
diff --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h
index db20b968a..33b36f53c 100644
--- a/clang/include/clang/Basic/DarwinSDKInfo.h
+++ b/clang/include/clang/Basic/DarwinSDKInfo.h
@@ -72,6 +72,13 @@ public:
llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment);
}
+ /// Returns the os-environment mapping pair that's used to represent the
+ /// iOS -> visionOS version mapping.
+ static inline constexpr OSEnvPair iOStoXROSPair() {
+ return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
+ llvm::Triple::XROS, llvm::Triple::UnknownEnvironment);
+ }
+
private:
StorageType Value;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index e2eada24f..26290b3ba 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2415,6 +2415,48 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+ ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
+ NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
+ Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform,
+ IIEnvironment);
+ if (NewAttr)
+ D->addAttr(NewAttr);
+ }
+ } else if (S.Context.getTargetInfo().getTriple().isXROS()) {
+ // Transcribe "ios" to "visionos" (and add a new attribute) if the versioning
+ // matches before the start of the visionOS platform.
+ IdentifierInfo *NewII = nullptr;
+ if (II->getName() == "ios")
+ NewII = &S.Context.Idents.get("xros");
+ else if (II->getName() == "ios_app_extension")
+ NewII = &S.Context.Idents.get("xros_app_extension");
+
+ if (NewII) {
+ const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
+ const auto *IOSToXROSMapping =
+ SDKInfo ? SDKInfo->getVersionMapping(
+ DarwinSDKInfo::OSEnvPair::iOStoXROSPair())
+ : nullptr;
+
+ auto AdjustTvOSVersion =
+ [IOSToXROSMapping](VersionTuple Version) -> VersionTuple {
+ if (Version.empty())
+ return Version;
+
+ if (IOSToXROSMapping) {
+ if (auto MappedVersion = IOSToXROSMapping->map(
+ Version, VersionTuple(1, 0), std::nullopt)) {
+ return *MappedVersion;
+ }
+ }
+ return Version;
+ };
+
+ auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
+ auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
+ auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
+
AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,Patch to fix release/21.x
--- llvm-project-stable-20250402/clang/include/clang/Basic/DarwinSDKInfo.orig.h 2025-06-07 04:17:57
+++ llvm-project-stable-20250402/clang/include/clang/Basic/DarwinSDKInfo.h 2025-10-04 09:35:43
@@ -72,6 +72,13 @@
llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment);
}
+ /// Returns the os-environment mapping pair that's used to represent the
+ /// iOS -> visionOS version mapping.
+ static inline constexpr OSEnvPair iOStoXROSPair() {
+ return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment,
+ llvm::Triple::XROS, llvm::Triple::UnknownEnvironment);
+ }
+
private:
StorageType Value;
--- llvm-project-stable-20250402/clang/lib/Sema/SemaDeclAttr.orig.cpp 2025-06-07 04:17:57
+++ llvm-project-stable-20250402/clang/lib/Sema/SemaDeclAttr.cpp 2025-10-04 09:35:28
@@ -2636,6 +2636,48 @@
if (IOSToTvOSMapping) {
if (auto MappedVersion = IOSToTvOSMapping->map(
Version, VersionTuple(0, 0), std::nullopt)) {
+ return *MappedVersion;
+ }
+ }
+ return Version;
+ };
+
+ auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
+ auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
+ auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
+
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+ ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
+ NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
+ Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform,
+ IIEnvironment);
+ if (NewAttr)
+ D->addAttr(NewAttr);
+ }
+ } else if (S.Context.getTargetInfo().getTriple().isXROS()) {
+ // Transcribe "ios" to "visionos" (and add a new attribute) if the versioning
+ // matches before the start of the visionOS platform.
+ IdentifierInfo *NewII = nullptr;
+ if (II->getName() == "ios")
+ NewII = &S.Context.Idents.get("xros");
+ else if (II->getName() == "ios_app_extension")
+ NewII = &S.Context.Idents.get("xros_app_extension");
+
+ if (NewII) {
+ const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
+ const auto *IOSToXROSMapping =
+ SDKInfo ? SDKInfo->getVersionMapping(
+ DarwinSDKInfo::OSEnvPair::iOStoXROSPair())
+ : nullptr;
+
+ auto AdjustTvOSVersion =
+ [IOSToXROSMapping](VersionTuple Version) -> VersionTuple {
+ if (Version.empty())
+ return Version;
+
+ if (IOSToXROSMapping) {
+ if (auto MappedVersion = IOSToXROSMapping->map(
+ Version, VersionTuple(1, 0), std::nullopt)) {
return *MappedVersion;
}
}akien-mga
Metadata
Metadata
Assignees
Labels
No labels