Skip to content

Commit e8225e0

Browse files
authored
Merge pull request swiftlang#78935 from tshortli/resolve-domain-in-semantic-available-attr-request
Parse/Sema: Resolve availability domains in SemanticAvailableAttrRequest
2 parents 3d2da98 + 1284001 commit e8225e0

14 files changed

+239
-134
lines changed

include/swift/AST/Attr.h

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,17 @@ class AvailableAttr : public DeclAttribute {
737737
NoAsync,
738738
};
739739

740-
AvailableAttr(SourceLoc AtLoc, SourceRange Range,
741-
const AvailabilityDomain &Domain, Kind Kind, StringRef Message,
740+
AvailableAttr(SourceLoc AtLoc, SourceRange Range, AvailabilityDomain Domain,
741+
SourceLoc DomainLoc, Kind Kind, StringRef Message,
742+
StringRef Rename, const llvm::VersionTuple &Introduced,
743+
SourceRange IntroducedRange,
744+
const llvm::VersionTuple &Deprecated,
745+
SourceRange DeprecatedRange,
746+
const llvm::VersionTuple &Obsoleted, SourceRange ObsoletedRange,
747+
bool Implicit, bool IsSPI);
748+
749+
AvailableAttr(SourceLoc AtLoc, SourceRange Range, StringRef DomainString,
750+
SourceLoc DomainLoc, Kind Kind, StringRef Message,
742751
StringRef Rename, const llvm::VersionTuple &Introduced,
743752
SourceRange IntroducedRange,
744753
const llvm::VersionTuple &Deprecated,
@@ -749,19 +758,47 @@ class AvailableAttr : public DeclAttribute {
749758
private:
750759
friend class SemanticAvailableAttr;
751760

752-
AvailabilityDomain Domain;
761+
union {
762+
AvailabilityDomain Domain;
763+
StringRef DomainString;
764+
};
765+
const SourceLoc DomainLoc;
753766

754767
const StringRef Message;
755768
const StringRef Rename;
756769

757-
const llvm::VersionTuple Introduced;
770+
llvm::VersionTuple Introduced;
758771
const SourceRange IntroducedRange;
759-
const llvm::VersionTuple Deprecated;
772+
llvm::VersionTuple Deprecated;
760773
const SourceRange DeprecatedRange;
761-
const llvm::VersionTuple Obsoleted;
774+
llvm::VersionTuple Obsoleted;
762775
const SourceRange ObsoletedRange;
763776

764777
public:
778+
/// Returns true if the `AvailabilityDomain` associated with the attribute
779+
/// has been resolved successfully.
780+
bool hasCachedDomain() const { return Bits.AvailableAttr.HasDomain; }
781+
782+
/// Returns the `AvailabilityDomain` associated with the attribute, or
783+
/// `std::nullopt` if it has either not yet been resolved or could not be
784+
/// resolved successfully.
785+
std::optional<AvailabilityDomain> getCachedDomain() const {
786+
if (hasCachedDomain())
787+
return Domain;
788+
return std::nullopt;
789+
}
790+
791+
/// If the attribute does not already have a cached `AvailabilityDomain`, this
792+
/// returns the domain string that was written in source, from which an
793+
/// `AvailabilityDomain` can be resolved.
794+
std::optional<StringRef> getDomainString() const {
795+
if (hasCachedDomain())
796+
return std::nullopt;
797+
return DomainString;
798+
}
799+
800+
SourceLoc getDomainLoc() const { return DomainLoc; }
801+
765802
/// Returns the parsed version for `introduced:`.
766803
std::optional<llvm::VersionTuple> getRawIntroduced() const {
767804
if (Introduced.empty())
@@ -813,19 +850,6 @@ class AvailableAttr : public DeclAttribute {
813850
/// Whether this attribute was spelled `@_spi_available`.
814851
bool isSPI() const { return Bits.AvailableAttr.IsSPI; }
815852

816-
/// Returns the `AvailabilityDomain` associated with the attribute, or
817-
/// `std::nullopt` if it has either not yet been resolved or could not be
818-
/// resolved successfully.
819-
std::optional<AvailabilityDomain> getCachedDomain() const {
820-
if (hasCachedDomain())
821-
return Domain;
822-
return std::nullopt;
823-
}
824-
825-
/// Returns true if the `AvailabilityDomain` associated with the attribute
826-
/// has been resolved successfully.
827-
bool hasCachedDomain() const { return Bits.AvailableAttr.HasDomain; }
828-
829853
/// Returns the kind of availability the attribute specifies.
830854
Kind getKind() const { return static_cast<Kind>(Bits.AvailableAttr.Kind); }
831855

@@ -888,6 +912,18 @@ class AvailableAttr : public DeclAttribute {
888912
private:
889913
friend class SemanticAvailableAttrRequest;
890914

915+
void setRawIntroduced(llvm::VersionTuple version) { Introduced = version; }
916+
917+
void setRawDeprecated(llvm::VersionTuple version) { Deprecated = version; }
918+
919+
void setRawObsoleted(llvm::VersionTuple version) { Obsoleted = version; }
920+
921+
void setCachedDomain(AvailabilityDomain domain) {
922+
assert(!Bits.AvailableAttr.HasDomain);
923+
Domain = domain;
924+
Bits.AvailableAttr.HasDomain = true;
925+
}
926+
891927
bool hasComputedSemanticAttr() const {
892928
return Bits.AvailableAttr.HasComputedSemanticAttr;
893929
}

include/swift/AST/AvailabilityDomain.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ class AvailabilityDomain final {
140140
return AvailabilityDomain(Kind::Embedded);
141141
}
142142

143+
/// Returns the built-in availability domain identified by the given string.
144+
static std::optional<AvailabilityDomain>
145+
builtinDomainForString(StringRef string);
146+
143147
Kind getKind() const {
144148
if (auto inlineDomain = getInlineDomain())
145149
return inlineDomain->getKind();

include/swift/AST/DiagnosticsParse.def

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,16 +1579,6 @@ ERROR(attr_availability_expected_equal,none,
15791579
ERROR(attr_availability_expected_version,none,
15801580
"expected version number in '%0' attribute", (StringRef))
15811581

1582-
WARNING(attr_availability_platform_agnostic_expected_option,none,
1583-
"expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute "
1584-
"for platform '%1'", (StringRef, StringRef))
1585-
WARNING(attr_availability_platform_agnostic_expected_deprecated_version,none,
1586-
"expected version number with 'deprecated' in '%0' attribute for "
1587-
"platform '%1'", (StringRef, StringRef))
1588-
WARNING(attr_availability_platform_agnostic_infeasible_option,none,
1589-
"'%0' cannot be used in '%1' attribute for platform '%2'",
1590-
(StringRef, StringRef, StringRef))
1591-
15921582
WARNING(attr_availability_nonspecific_platform_unexpected_version,none,
15931583
"unexpected version number in '%0' attribute for non-specific platform "
15941584
"'*'", (StringRef))

include/swift/AST/DiagnosticsSema.def

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6715,6 +6715,16 @@ NOTE(type_eraser_init_spi,none,
67156715
// MARK: @available
67166716
//------------------------------------------------------------------------------
67176717

6718+
WARNING(attr_availability_expected_deprecated_version, none,
6719+
"expected version number with 'deprecated' in '%0' attribute for "
6720+
"platform '%1'", (StringRef, StringRef))
6721+
WARNING(attr_availability_cannot_be_used_for_domain, none,
6722+
"'%0' cannot be used in '%1' attribute for platform '%2'",
6723+
(StringRef, StringRef, StringRef))
6724+
WARNING(attr_availability_expected_version_spec, none,
6725+
"expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute "
6726+
"for platform '%1'", (StringRef, StringRef))
6727+
67186728
ERROR(availability_decl_unavailable, none,
67196729
"%0 is unavailable%select{ in %2|}1%select{|: %3}3",
67206730
(const ValueDecl *, bool, StringRef, StringRef))

lib/AST/Attr.cpp

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,22 +2109,35 @@ Type RawLayoutAttr::getResolvedCountType(StructDecl *sd) const {
21092109
}
21102110

21112111
AvailableAttr::AvailableAttr(
2112-
SourceLoc AtLoc, SourceRange Range, const AvailabilityDomain &Domain,
2113-
Kind Kind, StringRef Message, StringRef Rename,
2112+
SourceLoc AtLoc, SourceRange Range, AvailabilityDomain Domain,
2113+
SourceLoc DomainLoc, Kind Kind, StringRef Message, StringRef Rename,
21142114
const llvm::VersionTuple &Introduced, SourceRange IntroducedRange,
21152115
const llvm::VersionTuple &Deprecated, SourceRange DeprecatedRange,
21162116
const llvm::VersionTuple &Obsoleted, SourceRange ObsoletedRange,
21172117
bool Implicit, bool IsSPI)
21182118
: DeclAttribute(DeclAttrKind::Available, AtLoc, Range, Implicit),
2119-
Domain(Domain), Message(Message), Rename(Rename), Introduced(Introduced),
2120-
IntroducedRange(IntroducedRange), Deprecated(Deprecated),
2121-
DeprecatedRange(DeprecatedRange), Obsoleted(Obsoleted),
2122-
ObsoletedRange(ObsoletedRange) {
2119+
Domain(Domain), DomainLoc(DomainLoc), Message(Message), Rename(Rename),
2120+
Introduced(Introduced), IntroducedRange(IntroducedRange),
2121+
Deprecated(Deprecated), DeprecatedRange(DeprecatedRange),
2122+
Obsoleted(Obsoleted), ObsoletedRange(ObsoletedRange) {
21232123
Bits.AvailableAttr.Kind = static_cast<uint8_t>(Kind);
2124-
Bits.AvailableAttr.HasComputedSemanticAttr = false;
21252124
Bits.AvailableAttr.HasDomain = true;
2126-
Bits.AvailableAttr.HasComputedRenamedDecl = false;
2127-
Bits.AvailableAttr.HasRenamedDecl = false;
2125+
Bits.AvailableAttr.IsSPI = IsSPI;
2126+
}
2127+
2128+
AvailableAttr::AvailableAttr(
2129+
SourceLoc AtLoc, SourceRange Range, StringRef DomainString,
2130+
SourceLoc DomainLoc, Kind Kind, StringRef Message, StringRef Rename,
2131+
const llvm::VersionTuple &Introduced, SourceRange IntroducedRange,
2132+
const llvm::VersionTuple &Deprecated, SourceRange DeprecatedRange,
2133+
const llvm::VersionTuple &Obsoleted, SourceRange ObsoletedRange,
2134+
bool Implicit, bool IsSPI)
2135+
: DeclAttribute(DeclAttrKind::Available, AtLoc, Range, Implicit),
2136+
DomainString(DomainString), DomainLoc(DomainLoc), Message(Message),
2137+
Rename(Rename), Introduced(Introduced), IntroducedRange(IntroducedRange),
2138+
Deprecated(Deprecated), DeprecatedRange(DeprecatedRange),
2139+
Obsoleted(Obsoleted), ObsoletedRange(ObsoletedRange) {
2140+
Bits.AvailableAttr.Kind = static_cast<uint8_t>(Kind);
21282141
Bits.AvailableAttr.IsSPI = IsSPI;
21292142
}
21302143

@@ -2133,7 +2146,7 @@ AvailableAttr *AvailableAttr::createUniversallyUnavailable(ASTContext &C,
21332146
StringRef Rename) {
21342147
return new (C) AvailableAttr(
21352148
SourceLoc(), SourceRange(), AvailabilityDomain::forUniversal(),
2136-
Kind::Unavailable, Message, Rename,
2149+
SourceLoc(), Kind::Unavailable, Message, Rename,
21372150
/*Introduced=*/{}, SourceRange(), /*Deprecated=*/{}, SourceRange(),
21382151
/*Obsoleted=*/{}, SourceRange(),
21392152
/*Implicit=*/false,
@@ -2145,7 +2158,7 @@ AvailableAttr *AvailableAttr::createUniversallyDeprecated(ASTContext &C,
21452158
StringRef Rename) {
21462159
return new (C) AvailableAttr(
21472160
SourceLoc(), SourceRange(), AvailabilityDomain::forUniversal(),
2148-
Kind::Deprecated, Message, Rename,
2161+
SourceLoc(), Kind::Deprecated, Message, Rename,
21492162
/*Introduced=*/{}, SourceRange(), /*Deprecated=*/{}, SourceRange(),
21502163
/*Obsoleted=*/{}, SourceRange(),
21512164
/*Implicit=*/false,
@@ -2157,7 +2170,7 @@ AvailableAttr *AvailableAttr::createUnavailableInSwift(ASTContext &C,
21572170
StringRef Rename) {
21582171
return new (C) AvailableAttr(
21592172
SourceLoc(), SourceRange(), AvailabilityDomain::forSwiftLanguage(),
2160-
Kind::Unavailable, Message, Rename,
2173+
SourceLoc(), Kind::Unavailable, Message, Rename,
21612174
/*Introduced=*/{}, SourceRange(), /*Deprecated=*/{}, SourceRange(),
21622175
/*Obsoleted=*/{}, SourceRange(),
21632176
/*Implicit=*/false,
@@ -2169,7 +2182,7 @@ AvailableAttr *AvailableAttr::createSwiftLanguageModeVersioned(
21692182
llvm::VersionTuple Introduced, llvm::VersionTuple Obsoleted) {
21702183
return new (C) AvailableAttr(
21712184
SourceLoc(), SourceRange(), AvailabilityDomain::forSwiftLanguage(),
2172-
Kind::Default, Message, Rename, Introduced, SourceRange(),
2185+
SourceLoc(), Kind::Default, Message, Rename, Introduced, SourceRange(),
21732186
/*Deprecated=*/{}, SourceRange(), Obsoleted, SourceRange(),
21742187
/*Implicit=*/false,
21752188
/*SPI=*/false);
@@ -2181,8 +2194,8 @@ AvailableAttr *AvailableAttr::createPlatformVersioned(
21812194
llvm::VersionTuple Obsoleted) {
21822195
return new (C) AvailableAttr(
21832196
SourceLoc(), SourceRange(), AvailabilityDomain::forPlatform(Platform),
2184-
Kind::Default, Message, Rename, Introduced, SourceRange(), Deprecated,
2185-
SourceRange(), Obsoleted, SourceRange(),
2197+
SourceLoc(), Kind::Default, Message, Rename, Introduced, SourceRange(),
2198+
Deprecated, SourceRange(), Obsoleted, SourceRange(),
21862199
/*Implicit=*/false,
21872200
/*SPI=*/false);
21882201
}
@@ -2195,8 +2208,8 @@ bool BackDeployedAttr::isActivePlatform(const ASTContext &ctx,
21952208
AvailableAttr *AvailableAttr::clone(ASTContext &C, bool implicit) const {
21962209
return new (C) AvailableAttr(
21972210
implicit ? SourceLoc() : AtLoc, implicit ? SourceRange() : getRange(),
2198-
Domain, getKind(), Message, Rename, Introduced,
2199-
implicit ? SourceRange() : IntroducedRange, Deprecated,
2211+
Domain, implicit ? SourceLoc() : DomainLoc, getKind(), Message, Rename,
2212+
Introduced, implicit ? SourceRange() : IntroducedRange, Deprecated,
22002213
implicit ? SourceRange() : DeprecatedRange, Obsoleted,
22012214
implicit ? SourceRange() : ObsoletedRange, implicit, isSPI());
22022215
}

lib/AST/Availability.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,10 @@ static AvailableAttr *createAvailableAttr(AvailabilityDomain Domain,
191191
Inferred.Obsoleted.value_or(llvm::VersionTuple());
192192

193193
return new (Context) AvailableAttr(
194-
SourceLoc(), SourceRange(), Domain, Inferred.Kind, Inferred.Message,
195-
Inferred.Rename, Introduced, SourceRange(), Deprecated, SourceRange(),
196-
Obsoleted, SourceRange(), /*Implicit=*/true, Inferred.IsSPI);
194+
SourceLoc(), SourceRange(), Domain, SourceLoc(), Inferred.Kind,
195+
Inferred.Message, Inferred.Rename, Introduced, SourceRange(), Deprecated,
196+
SourceRange(), Obsoleted, SourceRange(), /*Implicit=*/true,
197+
Inferred.IsSPI);
197198
}
198199

199200
void AvailabilityInference::applyInferredAvailableAttrs(

lib/AST/AvailabilityDomain.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,28 @@
1313
#include "swift/AST/AvailabilityDomain.h"
1414
#include "swift/AST/ASTContext.h"
1515
#include "swift/AST/Decl.h"
16+
#include "llvm/ADT/StringSwitch.h"
1617

1718
using namespace swift;
1819

20+
std::optional<AvailabilityDomain>
21+
AvailabilityDomain::builtinDomainForString(StringRef string) {
22+
auto domain = llvm::StringSwitch<std::optional<AvailabilityDomain>>(string)
23+
.Case("*", AvailabilityDomain::forUniversal())
24+
.Case("swift", AvailabilityDomain::forSwiftLanguage())
25+
.Case("_PackageDescription",
26+
AvailabilityDomain::forPackageDescription())
27+
.Default(std::nullopt);
28+
29+
if (domain)
30+
return domain;
31+
32+
if (auto platformKind = platformFromString(string))
33+
return AvailabilityDomain::forPlatform(*platformKind);
34+
35+
return std::nullopt;
36+
}
37+
1938
bool AvailabilityDomain::isActive(const ASTContext &ctx) const {
2039
switch (getKind()) {
2140
case Kind::Universal:

lib/AST/TypeCheckRequests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,4 +2735,6 @@ void SemanticAvailableAttrRequest::cacheResult(
27352735
std::optional<SemanticAvailableAttr> value) const {
27362736
AvailableAttr *attr = const_cast<AvailableAttr *>(std::get<0>(getStorage()));
27372737
attr->setComputedSemanticAttr();
2738+
if (!value)
2739+
attr->setInvalid();
27382740
}

lib/ClangImporter/ImportDecl.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8078,7 +8078,7 @@ void addCompletionHandlerAttribute(Decl *asyncImport,
80788078
llvm::VersionTuple NoVersion;
80798079
auto *attr = new (SwiftContext) AvailableAttr(
80808080
SourceLoc(), SourceRange(), AvailabilityDomain::forUniversal(),
8081-
AvailableAttr::Kind::Default,
8081+
SourceLoc(), AvailableAttr::Kind::Default,
80828082
/*Message=*/"", /*Rename=*/"", /*Introduced=*/NoVersion, SourceRange(),
80838083
/*Deprecated=*/NoVersion, SourceRange(),
80848084
/*Obsoleted=*/NoVersion, SourceRange(),
@@ -9107,12 +9107,12 @@ void ClangImporter::Implementation::importAttributes(
91079107
if (!replacement.empty())
91089108
swiftReplacement = getSwiftNameFromClangName(replacement);
91099109

9110-
auto AvAttr = new (C)
9111-
AvailableAttr(SourceLoc(), SourceRange(),
9112-
AvailabilityDomain::forPlatform(*platformK), AttrKind,
9113-
message, swiftReplacement, introduced, SourceRange(),
9114-
deprecated, SourceRange(), obsoleted, SourceRange(),
9115-
/*Implicit=*/false, EnableClangSPI && IsSPI);
9110+
auto AvAttr = new (C) AvailableAttr(
9111+
SourceLoc(), SourceRange(),
9112+
AvailabilityDomain::forPlatform(*platformK), SourceLoc(), AttrKind,
9113+
message, swiftReplacement, introduced, SourceRange(), deprecated,
9114+
SourceRange(), obsoleted, SourceRange(),
9115+
/*Implicit=*/false, EnableClangSPI && IsSPI);
91169116

91179117
MappedDecl->getAttrs().add(AvAttr);
91189118
}

0 commit comments

Comments
 (0)