forked from OSchip/llvm-project
				
			Support tvOS and watchOS availability attributes
llvm-svn: 251711
This commit is contained in:
		
							parent
							
								
									5627d3935a
								
							
						
					
					
						commit
						7a73cc71d7
					
				| 
						 | 
					@ -456,8 +456,12 @@ def Availability : InheritableAttr {
 | 
				
			||||||
             .Case("android", "Android")
 | 
					             .Case("android", "Android")
 | 
				
			||||||
             .Case("ios", "iOS")
 | 
					             .Case("ios", "iOS")
 | 
				
			||||||
             .Case("macosx", "OS X")
 | 
					             .Case("macosx", "OS X")
 | 
				
			||||||
 | 
					             .Case("tvos", "tvOS")
 | 
				
			||||||
 | 
					             .Case("watchos", "watchOS")
 | 
				
			||||||
             .Case("ios_app_extension", "iOS (App Extension)")
 | 
					             .Case("ios_app_extension", "iOS (App Extension)")
 | 
				
			||||||
             .Case("macosx_app_extension", "OS X (App Extension)")
 | 
					             .Case("macosx_app_extension", "OS X (App Extension)")
 | 
				
			||||||
 | 
					             .Case("tvos_app_extension", "tvOS (App Extension)")
 | 
				
			||||||
 | 
					             .Case("watchos_app_extension", "watchOS (App Extension)")
 | 
				
			||||||
             .Default(llvm::StringRef());
 | 
					             .Default(llvm::StringRef());
 | 
				
			||||||
} }];
 | 
					} }];
 | 
				
			||||||
  let HasCustomParsing = 1;
 | 
					  let HasCustomParsing = 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -580,6 +580,14 @@ are:
 | 
				
			||||||
  Apple's Mac OS X operating system.  The minimum deployment target is
 | 
					  Apple's Mac OS X operating system.  The minimum deployment target is
 | 
				
			||||||
  specified by the ``-mmacosx-version-min=*version*`` command-line argument.
 | 
					  specified by the ``-mmacosx-version-min=*version*`` command-line argument.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					``tvos``
 | 
				
			||||||
 | 
					  Apple's tvOS operating system.  The minimum deployment target is specified by
 | 
				
			||||||
 | 
					  the ``-mtvos-version-min=*version*`` command-line argument.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					``watchos``
 | 
				
			||||||
 | 
					  Apple's watchOS operating system.  The minimum deployment target is specified by
 | 
				
			||||||
 | 
					  the ``-mwatchos-version-min=*version*`` command-line argument.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
A declaration can be used even when deploying back to a platform version prior
 | 
					A declaration can be used even when deploying back to a platform version prior
 | 
				
			||||||
to when the declaration was introduced.  When this happens, the declaration is
 | 
					to when the declaration was introduced.  When this happens, the declaration is
 | 
				
			||||||
`weakly linked
 | 
					`weakly linked
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1062,6 +1062,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
 | 
				
			||||||
      .Case("attribute_availability_with_message", true)
 | 
					      .Case("attribute_availability_with_message", true)
 | 
				
			||||||
      .Case("attribute_availability_app_extension", true)
 | 
					      .Case("attribute_availability_app_extension", true)
 | 
				
			||||||
      .Case("attribute_availability_with_version_underscores", true)
 | 
					      .Case("attribute_availability_with_version_underscores", true)
 | 
				
			||||||
 | 
					      .Case("attribute_availability_tvos", true)
 | 
				
			||||||
 | 
					      .Case("attribute_availability_watchos", true)
 | 
				
			||||||
      .Case("attribute_cf_returns_not_retained", true)
 | 
					      .Case("attribute_cf_returns_not_retained", true)
 | 
				
			||||||
      .Case("attribute_cf_returns_retained", true)
 | 
					      .Case("attribute_cf_returns_retained", true)
 | 
				
			||||||
      .Case("attribute_cf_returns_on_parameters", true)
 | 
					      .Case("attribute_cf_returns_on_parameters", true)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1863,6 +1863,22 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
 | 
				
			||||||
        continue;
 | 
					        continue;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If there is an existing availability attribute for this platform that
 | 
				
			||||||
 | 
					      // is explicit and the new one is implicit use the explicit one and
 | 
				
			||||||
 | 
					      // discard the new implicit attribute.
 | 
				
			||||||
 | 
					      if (OldAA->getRange().isValid() && Range.isInvalid()) {
 | 
				
			||||||
 | 
					        return nullptr;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // If there is an existing attribute for this platform that is implicit
 | 
				
			||||||
 | 
					      // and the new attribute is explicit then erase the old one and
 | 
				
			||||||
 | 
					      // continue processing the attributes.
 | 
				
			||||||
 | 
					      if (Range.isValid() && OldAA->getRange().isInvalid()) {
 | 
				
			||||||
 | 
					        Attrs.erase(Attrs.begin() + i);
 | 
				
			||||||
 | 
					        --e;
 | 
				
			||||||
 | 
					        continue;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      FoundAny = true;
 | 
					      FoundAny = true;
 | 
				
			||||||
      VersionTuple OldIntroduced = OldAA->getIntroduced();
 | 
					      VersionTuple OldIntroduced = OldAA->getIntroduced();
 | 
				
			||||||
      VersionTuple OldDeprecated = OldAA->getDeprecated();
 | 
					      VersionTuple OldDeprecated = OldAA->getDeprecated();
 | 
				
			||||||
| 
						 | 
					@ -2000,6 +2016,74 @@ static void handleAvailabilityAttr(Sema &S, Decl *D,
 | 
				
			||||||
                                                      Index);
 | 
					                                                      Index);
 | 
				
			||||||
  if (NewAttr)
 | 
					  if (NewAttr)
 | 
				
			||||||
    D->addAttr(NewAttr);
 | 
					    D->addAttr(NewAttr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
 | 
				
			||||||
 | 
					  // matches before the start of the watchOS platform.
 | 
				
			||||||
 | 
					  if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
 | 
				
			||||||
 | 
					    IdentifierInfo *NewII = nullptr;
 | 
				
			||||||
 | 
					    if (II->getName() == "ios")
 | 
				
			||||||
 | 
					      NewII = &S.Context.Idents.get("watchos");
 | 
				
			||||||
 | 
					    else if (II->getName() == "ios_app_extension")
 | 
				
			||||||
 | 
					      NewII = &S.Context.Idents.get("watchos_app_extension");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (NewII) {
 | 
				
			||||||
 | 
					        auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple {
 | 
				
			||||||
 | 
					          if (Version.empty())
 | 
				
			||||||
 | 
					            return Version;
 | 
				
			||||||
 | 
					          auto Major = Version.getMajor();
 | 
				
			||||||
 | 
					          auto NewMajor = Major >= 9 ? Major - 7 : 0;
 | 
				
			||||||
 | 
					          if (NewMajor >= 2) {
 | 
				
			||||||
 | 
					            if (Version.getMinor().hasValue()) {
 | 
				
			||||||
 | 
					              if (Version.getSubminor().hasValue())
 | 
				
			||||||
 | 
					                return VersionTuple(NewMajor, Version.getMinor().getValue(),
 | 
				
			||||||
 | 
					                                    Version.getSubminor().getValue());
 | 
				
			||||||
 | 
					              else
 | 
				
			||||||
 | 
					                return VersionTuple(NewMajor, Version.getMinor().getValue());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return VersionTuple(2, 0);
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
 | 
				
			||||||
 | 
					        auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
 | 
				
			||||||
 | 
					        auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
 | 
				
			||||||
 | 
					                                                            SourceRange(),
 | 
				
			||||||
 | 
					                                                            NewII,
 | 
				
			||||||
 | 
					                                                            NewIntroduced,
 | 
				
			||||||
 | 
					                                                            NewDeprecated,
 | 
				
			||||||
 | 
					                                                            NewObsoleted,
 | 
				
			||||||
 | 
					                                                            IsUnavailable, Str,
 | 
				
			||||||
 | 
					                                                            Sema::AMK_None,
 | 
				
			||||||
 | 
					                                                            Index);
 | 
				
			||||||
 | 
					        if (NewAttr)
 | 
				
			||||||
 | 
					          D->addAttr(NewAttr);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
 | 
				
			||||||
 | 
					    // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
 | 
				
			||||||
 | 
					    // matches before the start of the tvOS platform.
 | 
				
			||||||
 | 
					    IdentifierInfo *NewII = nullptr;
 | 
				
			||||||
 | 
					    if (II->getName() == "ios")
 | 
				
			||||||
 | 
					      NewII = &S.Context.Idents.get("tvos");
 | 
				
			||||||
 | 
					    else if (II->getName() == "ios_app_extension")
 | 
				
			||||||
 | 
					      NewII = &S.Context.Idents.get("tvos_app_extension");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (NewII) {
 | 
				
			||||||
 | 
					        AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
 | 
				
			||||||
 | 
					                                                            SourceRange(),
 | 
				
			||||||
 | 
					                                                            NewII,
 | 
				
			||||||
 | 
					                                                            Introduced.Version,
 | 
				
			||||||
 | 
					                                                            Deprecated.Version,
 | 
				
			||||||
 | 
					                                                            Obsoleted.Version,
 | 
				
			||||||
 | 
					                                                            IsUnavailable, Str,
 | 
				
			||||||
 | 
					                                                            Sema::AMK_None,
 | 
				
			||||||
 | 
					                                                            Index);
 | 
				
			||||||
 | 
					        if (NewAttr)
 | 
				
			||||||
 | 
					          D->addAttr(NewAttr);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <class T>
 | 
					template <class T>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					// RUN: %clang_cc1 "-triple" "x86_64-apple-tvos3.0" -fsyntax-only -verify %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void f0(int) __attribute__((availability(tvos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					void f1(int) __attribute__((availability(tvos,introduced=2.1)));
 | 
				
			||||||
 | 
					void f2(int) __attribute__((availability(tvos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					void f3(int) __attribute__((availability(tvos,introduced=3.0)));
 | 
				
			||||||
 | 
					void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void f5(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					void f6(int) __attribute__((availability(tvos,deprecated=3.0)));
 | 
				
			||||||
 | 
					void f6(int) __attribute__((availability(tvos,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void test() {
 | 
				
			||||||
 | 
					  f0(0); // expected-warning{{'f0' is deprecated: first deprecated in tvOS 2.1}}
 | 
				
			||||||
 | 
					  f1(0);
 | 
				
			||||||
 | 
					  f2(0); // expected-warning{{'f2' is deprecated: first deprecated in tvOS 3.0}}
 | 
				
			||||||
 | 
					  f3(0);
 | 
				
			||||||
 | 
					  f4(0); // expected-error{{f4' is unavailable: obsoleted in tvOS 3.0}}
 | 
				
			||||||
 | 
					  f5(0); // expected-warning{{'f5' is deprecated: first deprecated in tvOS 3.0}}
 | 
				
			||||||
 | 
					  f6(0); // expected-warning{{'f6' is deprecated: first deprecated in tvOS 3.0}}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					// RUN: %clang_cc1 "-triple" "x86_64-apple-watchos3.0" -fsyntax-only -verify %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void f0(int) __attribute__((availability(watchos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					void f1(int) __attribute__((availability(watchos,introduced=2.1)));
 | 
				
			||||||
 | 
					void f2(int) __attribute__((availability(watchos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					void f3(int) __attribute__((availability(watchos,introduced=3.0)));
 | 
				
			||||||
 | 
					void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(watchos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void f5(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(watchos,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					void f6(int) __attribute__((availability(watchos,deprecated=3.0)));
 | 
				
			||||||
 | 
					void f6(int) __attribute__((availability(watchos,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void test() {
 | 
				
			||||||
 | 
					  f0(0); // expected-warning{{'f0' is deprecated: first deprecated in watchOS 2.1}}
 | 
				
			||||||
 | 
					  f1(0);
 | 
				
			||||||
 | 
					  f2(0); // expected-warning{{'f2' is deprecated: first deprecated in watchOS 3.0}}
 | 
				
			||||||
 | 
					  f3(0);
 | 
				
			||||||
 | 
					  f4(0); // expected-error{{f4' is unavailable: obsoleted in watchOS 3.0}}
 | 
				
			||||||
 | 
					  f5(0); // expected-warning{{'f5' is deprecated: first deprecated in watchOS 3.0}}
 | 
				
			||||||
 | 
					  f6(0); // expected-warning{{'f6' is deprecated: first deprecated in watchOS 3.0}}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue