[clang] [clang] Upstream visionOS Availability & DarwinSDKInfo APIs (PR #84279)

Cyndy Ishida via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 6 22:06:25 PST 2024


https://github.com/cyndyishida created https://github.com/llvm/llvm-project/pull/84279

Admittedly a bit awkward, `visionos` is the correct and accepted spelling for annotating availability for xrOS target triples. This patch detects errors and handles cases when `xros` is mistakenly passed. 
In addition, add APIs for introduced/deprecated/obsoleted versioning in DarwinSDKInfo mappings.

>From 64ff809b6325c9b6d4f957c9bbc2d9ffc83eaa15 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Wed, 6 Mar 2024 20:29:30 -0800
Subject: [PATCH 1/2] [clang] Support availability annotations for visionOS

Admittently a bit awkward, `visionos` is the correct and accepted
spelling for annotating availability for xros target triples. This patch
detects errors and handles cases when `xros` is mistakenly passed.
---
 clang/include/clang/Basic/Attr.td            |  8 ++++
 clang/lib/Parse/ParseDecl.cpp                |  5 ++-
 clang/lib/Parse/ParseExpr.cpp                |  3 +-
 clang/test/Sema/attr-availability-visionos.c | 39 ++++++++++++++++++++
 4 files changed, 53 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/attr-availability-visionos.c

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index fa191c7378dba4..ebb616fbe253fc 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -983,6 +983,8 @@ def Availability : InheritableAttr {
              .Case("watchos_app_extension", "watchOS (App Extension)")
              .Case("maccatalyst", "macCatalyst")
              .Case("maccatalyst_app_extension", "macCatalyst (App Extension)")
+             .Case("xros", "visionOS")
+             .Case("xros_app_extension", "visionOS (App Extension)")
              .Case("swift", "Swift")
              .Case("shadermodel", "HLSL ShaderModel")
              .Case("ohos", "OpenHarmony OS")
@@ -1000,6 +1002,8 @@ static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
              .Case("watchos_app_extension", "watchOSApplicationExtension")
              .Case("maccatalyst", "macCatalyst")
              .Case("maccatalyst_app_extension", "macCatalystApplicationExtension")
+             .Case("xros", "visionOS")
+             .Case("xros_app_extension", "visionOSApplicationExtension")
              .Case("zos", "z/OS")
              .Case("shadermodel", "ShaderModel")
              .Default(Platform);
@@ -1016,6 +1020,10 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
              .Case("watchOSApplicationExtension", "watchos_app_extension")
              .Case("macCatalyst", "maccatalyst")
              .Case("macCatalystApplicationExtension", "maccatalyst_app_extension")
+             .Case("visionOS", "xros")
+             .Case("visionOSApplicationExtension", "xros_app_extension")
+             .Case("visionos", "xros")
+             .Case("visionos_app_extension", "xros_app_extension")
              .Case("ShaderModel", "shadermodel")
              .Default(Platform);
 } }];
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 81f1c711269445..ee377b70964a28 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1234,8 +1234,11 @@ void Parser::ParseAvailabilityAttribute(
   }
   IdentifierLoc *Platform = ParseIdentifierLoc();
   if (const IdentifierInfo *const Ident = Platform->Ident) {
+    // Disallow xrOS for availability attributes.
+    if (Ident->getName().contains("xrOS") || Ident->getName().contains("xros"))
+      Diag(Platform->Loc, diag::warn_availability_unknown_platform) << Ident;
     // Canonicalize platform name from "macosx" to "macos".
-    if (Ident->getName() == "macosx")
+    else if (Ident->getName() == "macosx")
       Platform->Ident = PP.getIdentifierInfo("macos");
     // Canonicalize platform name from "macosx_app_extension" to
     // "macos_app_extension".
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 4bf954b5cc4db5..1f07eddb0fb378 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -3863,7 +3863,8 @@ std::optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
     StringRef Platform =
         AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
 
-    if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) {
+    if (AvailabilityAttr::getPrettyPlatformName(Platform).empty() ||
+        (GivenPlatform.contains("xros") || GivenPlatform.contains("xrOS"))) {
       Diag(PlatformIdentifier->Loc,
            diag::err_avail_query_unrecognized_platform_name)
           << GivenPlatform;
diff --git a/clang/test/Sema/attr-availability-visionos.c b/clang/test/Sema/attr-availability-visionos.c
new file mode 100644
index 00000000000000..2c388c5d529073
--- /dev/null
+++ b/clang/test/Sema/attr-availability-visionos.c
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -triple arm64-apple-xros1 -fapplication-extension -verify=visionos %s 2>&1
+
+__attribute__((availability(xros, unavailable))) // visionos-warning {{unknown platform 'xros' in availability macro}}
+void xros_unavail(); // visionos-note {{}}
+
+__attribute__((availability(xros_app_extension, unavailable))) // visionos-warning {{unknown platform 'xros_app_extension' in availability macro}}
+void xros_ext_unavail(); // visionos-note {{}}
+
+__attribute__((availability(visionOSApplicationExtension, unavailable)))
+void visionos_ext_unavail(); // visionos-note {{}}
+
+void use() {
+  xros_unavail(); // visionos-error {{'xros_unavail' is unavailable: not available on visionOS}}
+  xros_ext_unavail(); // visionos-error {{'xros_ext_unavail' is unavailable: not available on visionOS}}
+  visionos_ext_unavail(); // visionos-error {{'visionos_ext_unavail' is unavailable: not available on visionOS}}
+}
+
+__attribute__((availability(visionOS, introduced=1.0)))
+void visionos_introduced_1();
+
+__attribute__((availability(visionos, introduced=1.1)))
+void visionos_introduced_1_1(); // visionos-note 4 {{'visionos_introduced_1_1' has been marked as being introduced in visionOS 1.1 here, but the deployment target is visionOS 1}}
+
+void use2() {
+  if (__builtin_available(iOS 16.1, *))
+    visionos_introduced_1_1(); // visionos-warning {{'visionos_introduced_1_1' is only available on visionOS 1.1 or newer}} visionos-note {{enclose}}
+                              
+  if (__builtin_available(xrOS 1.1, *)) // visionos-error {{unrecognized platform name xrOS}}
+    visionos_introduced_1_1(); // visionos-warning {{'visionos_introduced_1_1' is only available on visionOS 1.1 or newer}} visionos-note {{enclose}}
+  
+  if (__builtin_available(xros_app_extension 1, *)) // visionos-error {{unrecognized platform name xros_app_extension}}
+    visionos_introduced_1_1(); // visionos-warning {{'visionos_introduced_1_1' is only available on visionOS 1.1 or newer}} visionos-note {{enclose}}
+
+  if (__builtin_available(visionOS 1.1, *))
+    visionos_introduced_1_1();
+
+  visionos_introduced_1();
+  visionos_introduced_1_1(); // visionos-warning {{'visionos_introduced_1_1' is only available on visionOS 1.1 or newer}} visionos-note {{enclose}}
+}

>From 769449fdfc84bdb30d669374c21833ae186bd066 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Wed, 6 Mar 2024 21:47:10 -0800
Subject: [PATCH 2/2] [clang][DarwinSDKInfo] Add remapping APIs for
 introduced/deprecated/obsoleted versioning

---
 clang/include/clang/Basic/DarwinSDKInfo.h   | 24 +++++++++++++++++++++
 clang/unittests/Basic/DarwinSDKInfoTest.cpp | 10 +++++++++
 2 files changed, 34 insertions(+)

diff --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h
index dedfbd934a7b63..db20b968a898ea 100644
--- a/clang/include/clang/Basic/DarwinSDKInfo.h
+++ b/clang/include/clang/Basic/DarwinSDKInfo.h
@@ -105,6 +105,30 @@ class DarwinSDKInfo {
     map(const VersionTuple &Key, const VersionTuple &MinimumValue,
         std::optional<VersionTuple> MaximumValue) const;
 
+    /// Remap the 'introduced' availability version.
+    /// If None is returned, the 'unavailable' availability should be used
+    /// instead.
+    std::optional<VersionTuple>
+    mapIntroducedAvailabilityVersion(const VersionTuple &Key) const {
+      // API_TO_BE_DEPRECATED is 100000.
+      if (Key.getMajor() == 100000)
+        return VersionTuple(100000);
+      // Use None for maximum to force unavailable behavior for
+      return map(Key, MinimumValue, std::nullopt);
+    }
+
+    /// Remap the 'deprecated' and 'obsoleted' availability version.
+    /// If None is returned for 'obsoleted', the 'unavailable' availability
+    /// should be used instead. If None is returned for 'deprecated', the
+    /// 'deprecated' version should be dropped.
+    std::optional<VersionTuple>
+    mapDeprecatedObsoletedAvailabilityVersion(const VersionTuple &Key) const {
+      // API_TO_BE_DEPRECATED is 100000.
+      if (Key.getMajor() == 100000)
+        return VersionTuple(100000);
+      return map(Key, MinimumValue, MaximumValue);
+    }
+
     static std::optional<RelatedTargetVersionMapping>
     parseJSON(const llvm::json::Object &Obj,
               VersionTuple MaximumDeploymentTarget);
diff --git a/clang/unittests/Basic/DarwinSDKInfoTest.cpp b/clang/unittests/Basic/DarwinSDKInfoTest.cpp
index 5f24e6eae515d2..7214f3bc8e19f4 100644
--- a/clang/unittests/Basic/DarwinSDKInfoTest.cpp
+++ b/clang/unittests/Basic/DarwinSDKInfoTest.cpp
@@ -168,6 +168,16 @@ TEST(DarwinSDKInfoTest, ParseAndTestMappingIOSDerived) {
   EXPECT_EQ(
       *Mapping->map(VersionTuple(13, 0), VersionTuple(), VersionTuple(99, 99)),
       VersionTuple(99, 99));
+
+  // Verify introduced, deprecated, and obsoleted mappings.
+  EXPECT_EQ(Mapping->mapIntroducedAvailabilityVersion(VersionTuple(10, 1)),
+            VersionTuple(10.0));
+  EXPECT_EQ(Mapping->mapDeprecatedObsoletedAvailabilityVersion(
+                VersionTuple(100000, 0)),
+            VersionTuple(100000));
+  EXPECT_EQ(
+      Mapping->mapDeprecatedObsoletedAvailabilityVersion(VersionTuple(13.0)),
+      VersionTuple(15, 0, 99));
 }
 
 TEST(DarwinSDKInfoTest, MissingKeys) {



More information about the cfe-commits mailing list