arphaman updated this revision to Diff 358511.
arphaman marked 11 inline comments as done.
arphaman added a comment.

Split patch and address review comments


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105257/new/

https://reviews.llvm.org/D105257

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Basic/DarwinSDKInfo.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json
  clang/test/Driver/Inputs/WatchOS6.0.sdk/SDKSettings.json
  clang/test/Driver/Inputs/iPhoneOS13.0.sdk/SDKSettings.json
  clang/test/Sema/Inputs/MacOSX11.0.sdk/SDKSettings.json
  clang/test/Sema/attr-availability-iosmac-infer-from-macos-no-sdk-settings.c
  clang/test/Sema/attr-availability-iosmac-infer-from-macos.c
  clang/test/Sema/attr-availability-maccatalyst.c

Index: clang/test/Sema/attr-availability-maccatalyst.c
===================================================================
--- clang/test/Sema/attr-availability-maccatalyst.c
+++ clang/test/Sema/attr-availability-maccatalyst.c
@@ -12,8 +12,8 @@
 void f0(int) __attribute__((availability(maccatalyst,introduced=2.0,deprecated=9.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
 void f1(int) __attribute__((availability(maccatalyst,introduced=2.1)));
 void f2(int) __attribute__((availability(macCatalyst,introduced=2.0,deprecated=9.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
-void f3(int) __attribute__((availability(macosx,introduced=10.1),  availability(maccatalyst,introduced=3.0, obsoleted=9.0))); // expected-note {{'f3' has been explicitly marked unavailable here}}
-void f32(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5),  availability(maccatalyst,introduced=3.0, obsoleted=9.0))); // expected-note {{'f32' has been explicitly marked unavailable here}}
+void f3(int) __attribute__((availability(maccatalyst,introduced=3.0, obsoleted=9.0))); // expected-note {{'f3' has been explicitly marked unavailable here}}
+void f32(int) __attribute__((availability(maccatalyst,introduced=3.0, obsoleted=9.0))); // expected-note {{'f32' has been explicitly marked unavailable here}}
 
 
 void f5(int) __attribute__((availability(maccatalyst,introduced=2.0))) __attribute__((availability(maccatalyst,deprecated=9.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
Index: clang/test/Sema/attr-availability-iosmac-infer-from-macos.c
===================================================================
--- /dev/null
+++ clang/test/Sema/attr-availability-iosmac-infer-from-macos.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 "-triple" "x86_64-apple-ios13.1-macabi" -isysroot %S/Inputs/MacOSX11.0.sdk -fsyntax-only -verify %s
+// RUN: %clang_cc1 "-triple" "x86_64-apple-ios14-macabi" -isysroot %S/Inputs/MacOSX11.0.sdk -DIOS14 -fsyntax-only -verify %s
+
+void f0(void) __attribute__((availability(macOS, introduced = 10.11)));
+void f1(void) __attribute__((availability(macOS, introduced = 10.15)));
+void f2(void) __attribute__(( // expected-note {{'f2' has been explicitly marked deprecated here}}
+    availability(macOS, introduced = 10.11,
+                 deprecated = 10.12)));
+void f3(void)
+    __attribute__((availability(macOS, introduced = 10.11, deprecated = 10.14)))
+    __attribute__((availability(iOS, introduced = 11.0)));
+
+void f4(void)
+__attribute__((availability(macOS, introduced = 10, deprecated = 100000)));
+
+void fAvail() __attribute__((availability(macOS, unavailable)));
+
+void f16() __attribute__((availability(macOS, introduced = 11.0)));
+#ifndef IOS14
+// expected-note@-2 {{here}}
+#endif
+
+void fObs() __attribute__((availability(macOS, introduced = 10.11, obsoleted = 10.15))); // expected-note {{'fObs' has been explicitly marked unavailable here}}
+
+void fAPItoDepr() __attribute__((availability(macOS, introduced = 10.11, deprecated = 100000)));
+
+void dontRemapFutureVers() __attribute__((availability(macOS, introduced = 20)));
+
+void usage() {
+  f0();
+  f1();
+  f2(); // expected-warning {{'f2' is deprecated: first deprecated in macCatalyst 13.1}}
+  f3();
+  f4();
+  fAvail();
+  f16();
+#ifndef IOS14
+  // expected-warning@-2 {{'f16' is only available on macCatalyst 14.0 or newer}} expected-note@-2 {{enclose}}
+#endif
+  fObs(); // expected-error {{'fObs' is unavailable: obsoleted in macCatalyst 13.1}}
+  fAPItoDepr();
+  dontRemapFutureVers();
+}
+
+#ifdef IOS14
+
+void f15_4(void) __attribute__((availability(macOS, introduced = 10.15, deprecated = 10.15.4))); // expected-note {{here}}
+void f15_3(void) __attribute__((availability(macOS, introduced = 10.15, deprecated = 10.15.3))); // expected-note {{here}}
+void f15_2(void) __attribute__((availability(macOS, introduced = 10.15, deprecated = 10.15.2))); // expected-note {{here}}
+
+void usage16() {
+  f15_2(); // expected-warning {{'f15_2' is deprecated: first deprecated in macCatalyst 13.3}}
+  f15_3(); // expected-warning {{'f15_3' is deprecated: first deprecated in macCatalyst 13.3.1}}
+  f15_4(); // expected-warning {{'f15_4' is deprecated: first deprecated in macCatalyst 13.4}}
+  f16();
+}
+
+#endif
Index: clang/test/Sema/attr-availability-iosmac-infer-from-macos-no-sdk-settings.c
===================================================================
--- /dev/null
+++ clang/test/Sema/attr-availability-iosmac-infer-from-macos-no-sdk-settings.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 "-triple" "x86_64-apple-ios13.1-macabi" -fsyntax-only -verify %s
+
+void f0(void) __attribute__((availability(macOS, introduced = 10.11)));
+// expected-warning@-1 {{macOS availability is ignored without a valid 'SDKSettings.json' in the SDK}}
+void f1(void) __attribute__((availability(macOS, introduced = 10.15)));
Index: clang/test/Sema/Inputs/MacOSX11.0.sdk/SDKSettings.json
===================================================================
--- /dev/null
+++ clang/test/Sema/Inputs/MacOSX11.0.sdk/SDKSettings.json
@@ -0,0 +1,23 @@
+{
+  "DefaultVariant": "macos", "DisplayName": "macOS 11",
+  "Version": "11.0",
+  "MaximumDeploymentTarget": "11.0.99",
+  "PropertyConditionFallbackNames": [], "VersionMap": {
+    "iOSMac_macOS": {
+      "13.2": "10.15.1",
+      "13.4": "10.15.4",
+      "13.3.1": "10.15.3",
+      "13.3": "10.15.2",
+      "13.1": "10.15",
+      "14.0": "11.0"
+    },
+    "macOS_iOSMac": {
+      "10.15.2": "13.3",
+      "11.0": "14.0",
+      "10.15": "13.1",
+      "10.15.3": "13.3.1",
+      "10.15.1": "13.2",
+      "10.15.4": "13.4"
+    }
+  }
+}
Index: clang/test/Driver/Inputs/iPhoneOS13.0.sdk/SDKSettings.json
===================================================================
--- clang/test/Driver/Inputs/iPhoneOS13.0.sdk/SDKSettings.json
+++ clang/test/Driver/Inputs/iPhoneOS13.0.sdk/SDKSettings.json
@@ -1 +1 @@
-{"Version":"13.0"}
+{"Version":"13.0", "MaximumDeploymentTarget": "13.0.99"}
Index: clang/test/Driver/Inputs/WatchOS6.0.sdk/SDKSettings.json
===================================================================
--- clang/test/Driver/Inputs/WatchOS6.0.sdk/SDKSettings.json
+++ clang/test/Driver/Inputs/WatchOS6.0.sdk/SDKSettings.json
@@ -1 +1 @@
-{"Version":"6.0.0"}
+{"Version":"6.0.0", "MaximumDeploymentTarget": "6.0.99"}
Index: clang/test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json
===================================================================
--- clang/test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json
+++ clang/test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json
@@ -1 +1 @@
-{"Version":"10.14"}
+{"Version":"10.14", "MaximumDeploymentTarget": "10.14.99"}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -23,6 +23,7 @@
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/CharInfo.h"
+#include "clang/Basic/DarwinSDKInfo.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetBuiltins.h"
@@ -2559,23 +2560,26 @@
   } else if (S.Context.getTargetInfo().getTriple().getOS() ==
                  llvm::Triple::IOS &&
              S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
+    auto GetSDKInfo = [&]() {
+      return S.getDarwinSDKInfoForAvailabilityChecking(AL.getRange().getBegin(),
+                                                       "macOS");
+    };
+
     // Transcribe "ios" to "maccatalyst" (and add a new attribute).
     IdentifierInfo *NewII = nullptr;
-    auto MinMacCatalystVersion = [](const VersionTuple &V) {
-      if (V.empty())
-        return V;
-      if (V.getMajor() < 13 ||
-          (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
-        return VersionTuple(13, 1); // The minimum Mac Catalyst version is 13.1.
-      return V;
-    };
     if (II->getName() == "ios")
       NewII = &S.Context.Idents.get("maccatalyst");
     else if (II->getName() == "ios_app_extension")
       NewII = &S.Context.Idents.get("maccatalyst_app_extension");
-    // FIXME: Add support for transcribing macOS availability using mapping from
-    // SDKSettings.json.
     if (NewII) {
+      auto MinMacCatalystVersion = [](const VersionTuple &V) {
+        if (V.empty())
+          return V;
+        if (V.getMajor() < 13 ||
+            (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
+          return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
+        return V;
+      };
       AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
           ND, AL.getRange(), NewII, true /*Implicit*/,
           MinMacCatalystVersion(Introduced.Version),
@@ -2585,6 +2589,50 @@
           PriorityModifier + Sema::AP_InferredFromOtherPlatform);
       if (NewAttr)
         D->addAttr(NewAttr);
+    } else if (II->getName() == "macos" && GetSDKInfo() &&
+               (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
+                !Obsoleted.Version.empty())) {
+      if (const auto *MacOStoMacCatalystMapping =
+              GetSDKInfo()->getVersionMapping(
+                  DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
+        // Infer Mac Catalyst availability from the macOS availability attribute
+        // if it has versioned availability. Don't infer 'unavailable'. This
+        // inferred availability has lower priority than the other availability
+        // attributes that are inferred from 'ios'.
+        NewII = &S.Context.Idents.get("maccatalyst");
+        auto RemapMacOSVersion =
+            [&](const VersionTuple &V) -> Optional<VersionTuple> {
+          if (V.empty())
+            return None;
+          // API_TO_BE_DEPRECATED is 100000.
+          if (V.getMajor() == 100000)
+            return VersionTuple(100000);
+          // The minimum iosmac version is 13.1
+          return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1), None);
+        };
+        Optional<VersionTuple> NewIntroduced =
+                                   RemapMacOSVersion(Introduced.Version),
+                               NewDeprecated =
+                                   RemapMacOSVersion(Deprecated.Version),
+                               NewObsoleted =
+                                   RemapMacOSVersion(Obsoleted.Version);
+        if (NewIntroduced || NewDeprecated || NewObsoleted) {
+          auto VersionOrEmptyVersion =
+              [](const Optional<VersionTuple> &V) -> VersionTuple {
+            return V ? *V : VersionTuple();
+          };
+          AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+              ND, AL.getRange(), NewII, true /*Implicit*/,
+              VersionOrEmptyVersion(NewIntroduced),
+              VersionOrEmptyVersion(NewDeprecated),
+              VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
+              IsStrict, Replacement, Sema::AMK_None,
+              PriorityModifier + Sema::AP_InferredFromOtherPlatform +
+                  Sema::AP_InferredFromOtherPlatform);
+          if (NewAttr)
+            D->addAttr(NewAttr);
+        }
+      }
     }
   }
 }
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -22,12 +22,14 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/PrettyDeclStackTrace.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/Basic/DarwinSDKInfo.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Stack.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/DelayedDiagnostic.h"
@@ -55,6 +57,27 @@
 
 ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
 
+DarwinSDKInfo *
+Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,
+                                              StringRef Platform) {
+  if (!CachedDarwinSDKInfo) {
+    auto SDKInfo = parseDarwinSDKInfo(
+        PP.getFileManager().getVirtualFileSystem(),
+        PP.getHeaderSearchInfo().getHeaderSearchOpts().Sysroot);
+    if (SDKInfo && *SDKInfo)
+      CachedDarwinSDKInfo =
+          std::make_unique<DarwinSDKInfo>(std::move(**SDKInfo));
+    else {
+      if (!SDKInfo)
+        llvm::consumeError(SDKInfo.takeError());
+      Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking)
+          << Platform;
+      CachedDarwinSDKInfo = std::unique_ptr<DarwinSDKInfo>();
+    }
+  }
+  return CachedDarwinSDKInfo->get();
+}
+
 IdentifierInfo *
 Sema::InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName,
                                                  unsigned int Index) {
Index: clang/lib/Basic/DarwinSDKInfo.cpp
===================================================================
--- clang/lib/Basic/DarwinSDKInfo.cpp
+++ clang/lib/Basic/DarwinSDKInfo.cpp
@@ -113,13 +113,8 @@
     return Result.takeError();
 
   if (const auto *Obj = Result->getAsObject()) {
-    // FIXME: Switch to use parseDarwinSDKSettingsJSON in the next commit.
-    auto VersionString = Obj->getString("Version");
-    if (VersionString) {
-      VersionTuple Version;
-      if (!Version.tryParse(*VersionString))
-        return DarwinSDKInfo(Version, Version);
-    }
+    if (auto SDKInfo = DarwinSDKInfo::parseDarwinSDKSettingsJSON(Obj))
+      return std::move(SDKInfo);
   }
   return llvm::make_error<llvm::StringError>("invalid SDKSettings.json",
                                              llvm::inconvertibleErrorCode());
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -115,6 +115,7 @@
   class CodeCompletionTUInfo;
   class CodeCompletionResult;
   class CoroutineBodyStmt;
+  class DarwinSDKInfo;
   class Decl;
   class DeclAccessPair;
   class DeclContext;
@@ -1525,6 +1526,8 @@
   /// assignment.
   llvm::DenseMap<const VarDecl *, int> RefsMinusAssignments;
 
+  Optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo;
+
 public:
   Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
        TranslationUnitKind TUKind = TU_Complete,
@@ -1553,6 +1556,8 @@
   ASTConsumer &getASTConsumer() const { return Consumer; }
   ASTMutationListener *getASTMutationListener() const;
   ExternalSemaSource* getExternalSource() const { return ExternalSource; }
+  DarwinSDKInfo *getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,
+                                                         StringRef Platform);
 
   ///Registers an external source. If an external source already exists,
   /// creates a multiplex external source and appends to it.
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3545,6 +3545,10 @@
   "use if (%select{@available|__builtin_available}0) instead">,
   InGroup<DiagGroup<"unsupported-availability-guard">>;
 
+def warn_missing_sdksettings_for_availability_checking : Warning<
+  "%0 availability is ignored without a valid 'SDKSettings.json' in the SDK">,
+  InGroup<DiagGroup<"ignored-availability-without-sdk-settings">>;
+
 // Thread Safety Attributes
 def warn_thread_attribute_ignored : Warning<
   "ignoring %0 attribute because its argument is invalid">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to