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