Skip to content

Commit 7a73cc7

Browse files
committed
Support tvOS and watchOS availability attributes
llvm-svn: 251711
1 parent 5627d39 commit 7a73cc7

File tree

6 files changed

+140
-0
lines changed

6 files changed

+140
-0
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,12 @@ def Availability : InheritableAttr {
456456
.Case("android", "Android")
457457
.Case("ios", "iOS")
458458
.Case("macosx", "OS X")
459+
.Case("tvos", "tvOS")
460+
.Case("watchos", "watchOS")
459461
.Case("ios_app_extension", "iOS (App Extension)")
460462
.Case("macosx_app_extension", "OS X (App Extension)")
463+
.Case("tvos_app_extension", "tvOS (App Extension)")
464+
.Case("watchos_app_extension", "watchOS (App Extension)")
461465
.Default(llvm::StringRef());
462466
} }];
463467
let HasCustomParsing = 1;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,14 @@ are:
580580
Apple's Mac OS X operating system. The minimum deployment target is
581581
specified by the ``-mmacosx-version-min=*version*`` command-line argument.
582582

583+
``tvos``
584+
Apple's tvOS operating system. The minimum deployment target is specified by
585+
the ``-mtvos-version-min=*version*`` command-line argument.
586+
587+
``watchos``
588+
Apple's watchOS operating system. The minimum deployment target is specified by
589+
the ``-mwatchos-version-min=*version*`` command-line argument.
590+
583591
A declaration can be used even when deploying back to a platform version prior
584592
to when the declaration was introduced. When this happens, the declaration is
585593
`weakly linked

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
10621062
.Case("attribute_availability_with_message", true)
10631063
.Case("attribute_availability_app_extension", true)
10641064
.Case("attribute_availability_with_version_underscores", true)
1065+
.Case("attribute_availability_tvos", true)
1066+
.Case("attribute_availability_watchos", true)
10651067
.Case("attribute_cf_returns_not_retained", true)
10661068
.Case("attribute_cf_returns_retained", true)
10671069
.Case("attribute_cf_returns_on_parameters", true)

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,6 +1863,22 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
18631863
continue;
18641864
}
18651865

1866+
// If there is an existing availability attribute for this platform that
1867+
// is explicit and the new one is implicit use the explicit one and
1868+
// discard the new implicit attribute.
1869+
if (OldAA->getRange().isValid() && Range.isInvalid()) {
1870+
return nullptr;
1871+
}
1872+
1873+
// If there is an existing attribute for this platform that is implicit
1874+
// and the new attribute is explicit then erase the old one and
1875+
// continue processing the attributes.
1876+
if (Range.isValid() && OldAA->getRange().isInvalid()) {
1877+
Attrs.erase(Attrs.begin() + i);
1878+
--e;
1879+
continue;
1880+
}
1881+
18661882
FoundAny = true;
18671883
VersionTuple OldIntroduced = OldAA->getIntroduced();
18681884
VersionTuple OldDeprecated = OldAA->getDeprecated();
@@ -2000,6 +2016,74 @@ static void handleAvailabilityAttr(Sema &S, Decl *D,
20002016
Index);
20012017
if (NewAttr)
20022018
D->addAttr(NewAttr);
2019+
2020+
// Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2021+
// matches before the start of the watchOS platform.
2022+
if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2023+
IdentifierInfo *NewII = nullptr;
2024+
if (II->getName() == "ios")
2025+
NewII = &S.Context.Idents.get("watchos");
2026+
else if (II->getName() == "ios_app_extension")
2027+
NewII = &S.Context.Idents.get("watchos_app_extension");
2028+
2029+
if (NewII) {
2030+
auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple {
2031+
if (Version.empty())
2032+
return Version;
2033+
auto Major = Version.getMajor();
2034+
auto NewMajor = Major >= 9 ? Major - 7 : 0;
2035+
if (NewMajor >= 2) {
2036+
if (Version.getMinor().hasValue()) {
2037+
if (Version.getSubminor().hasValue())
2038+
return VersionTuple(NewMajor, Version.getMinor().getValue(),
2039+
Version.getSubminor().getValue());
2040+
else
2041+
return VersionTuple(NewMajor, Version.getMinor().getValue());
2042+
}
2043+
}
2044+
2045+
return VersionTuple(2, 0);
2046+
};
2047+
2048+
auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2049+
auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2050+
auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2051+
2052+
AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
2053+
SourceRange(),
2054+
NewII,
2055+
NewIntroduced,
2056+
NewDeprecated,
2057+
NewObsoleted,
2058+
IsUnavailable, Str,
2059+
Sema::AMK_None,
2060+
Index);
2061+
if (NewAttr)
2062+
D->addAttr(NewAttr);
2063+
}
2064+
} else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2065+
// Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2066+
// matches before the start of the tvOS platform.
2067+
IdentifierInfo *NewII = nullptr;
2068+
if (II->getName() == "ios")
2069+
NewII = &S.Context.Idents.get("tvos");
2070+
else if (II->getName() == "ios_app_extension")
2071+
NewII = &S.Context.Idents.get("tvos_app_extension");
2072+
2073+
if (NewII) {
2074+
AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
2075+
SourceRange(),
2076+
NewII,
2077+
Introduced.Version,
2078+
Deprecated.Version,
2079+
Obsoleted.Version,
2080+
IsUnavailable, Str,
2081+
Sema::AMK_None,
2082+
Index);
2083+
if (NewAttr)
2084+
D->addAttr(NewAttr);
2085+
}
2086+
}
20032087
}
20042088

20052089
template <class T>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 "-triple" "x86_64-apple-tvos3.0" -fsyntax-only -verify %s
2+
3+
void f0(int) __attribute__((availability(tvos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
4+
void f1(int) __attribute__((availability(tvos,introduced=2.1)));
5+
void f2(int) __attribute__((availability(tvos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
6+
void f3(int) __attribute__((availability(tvos,introduced=3.0)));
7+
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}}
8+
9+
void f5(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
10+
void f6(int) __attribute__((availability(tvos,deprecated=3.0)));
11+
void f6(int) __attribute__((availability(tvos,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
12+
13+
void test() {
14+
f0(0); // expected-warning{{'f0' is deprecated: first deprecated in tvOS 2.1}}
15+
f1(0);
16+
f2(0); // expected-warning{{'f2' is deprecated: first deprecated in tvOS 3.0}}
17+
f3(0);
18+
f4(0); // expected-error{{f4' is unavailable: obsoleted in tvOS 3.0}}
19+
f5(0); // expected-warning{{'f5' is deprecated: first deprecated in tvOS 3.0}}
20+
f6(0); // expected-warning{{'f6' is deprecated: first deprecated in tvOS 3.0}}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 "-triple" "x86_64-apple-watchos3.0" -fsyntax-only -verify %s
2+
3+
void f0(int) __attribute__((availability(watchos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
4+
void f1(int) __attribute__((availability(watchos,introduced=2.1)));
5+
void f2(int) __attribute__((availability(watchos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
6+
void f3(int) __attribute__((availability(watchos,introduced=3.0)));
7+
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}}
8+
9+
void f5(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(watchos,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
10+
void f6(int) __attribute__((availability(watchos,deprecated=3.0)));
11+
void f6(int) __attribute__((availability(watchos,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
12+
13+
void test() {
14+
f0(0); // expected-warning{{'f0' is deprecated: first deprecated in watchOS 2.1}}
15+
f1(0);
16+
f2(0); // expected-warning{{'f2' is deprecated: first deprecated in watchOS 3.0}}
17+
f3(0);
18+
f4(0); // expected-error{{f4' is unavailable: obsoleted in watchOS 3.0}}
19+
f5(0); // expected-warning{{'f5' is deprecated: first deprecated in watchOS 3.0}}
20+
f6(0); // expected-warning{{'f6' is deprecated: first deprecated in watchOS 3.0}}
21+
}

0 commit comments

Comments
 (0)