Skip to content

Commit 7b8cbd7

Browse files
committed
AST: Store unresolved domain strings in AvailableAttr.
This is the first step towards resolving the AvailabilityDomain associated with an AvailableAttr during type checking instead of parsing.
1 parent 998ad51 commit 7b8cbd7

File tree

8 files changed

+91
-50
lines changed

8 files changed

+91
-50
lines changed

include/swift/AST/Attr.h

Lines changed: 40 additions & 16 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,7 +758,11 @@ 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;
@@ -762,6 +775,30 @@ class AvailableAttr : public DeclAttribute {
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

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/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
}

lib/Parse/ParseDecl.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -628,9 +628,9 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
628628
}
629629

630630
auto Attr = new (Context) AvailableAttr(
631-
AtLoc, SourceRange(AttrLoc, Tok.getLoc()), Domain, AttrKind, Message,
632-
Renamed, Introduced.Version, Introduced.Range, Deprecated.Version,
633-
Deprecated.Range, Obsoleted.Version, Obsoleted.Range,
631+
AtLoc, SourceRange(AttrLoc, Tok.getLoc()), Domain, PlatformLoc, AttrKind,
632+
Message, Renamed, Introduced.Version, Introduced.Range,
633+
Deprecated.Version, Deprecated.Range, Obsoleted.Version, Obsoleted.Range,
634634
/*Implicit=*/false, AttrName == SPI_AVAILABLE_ATTRNAME);
635635
return makeParserResult(Attr);
636636

@@ -899,7 +899,8 @@ bool Parser::parseAvailability(
899899
canonicalizePlatformVersion(Domain.getPlatformKind(), Version);
900900

901901
addAttribute(new (Context) AvailableAttr(
902-
AtLoc, attrRange, Domain, AvailableAttr::Kind::Default,
902+
AtLoc, attrRange, Domain, Spec->getSourceRange().Start,
903+
AvailableAttr::Kind::Default,
903904
/*Message=*/StringRef(),
904905
/*Rename=*/StringRef(),
905906
/*Introduced=*/Version,
@@ -4410,7 +4411,7 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes,
44104411
StringRef Message = "unavailable in embedded Swift", Renamed;
44114412
auto attr = new (Context) AvailableAttr(
44124413
AtLoc, SourceRange(AtLoc, attrLoc), AvailabilityDomain::forEmbedded(),
4413-
AvailableAttr::Kind::Unavailable, Message, Renamed,
4414+
SourceLoc(), AvailableAttr::Kind::Unavailable, Message, Renamed,
44144415
llvm::VersionTuple(), SourceRange(), llvm::VersionTuple(),
44154416
SourceRange(), llvm::VersionTuple(), SourceRange(),
44164417
/*Implicit=*/false, /*IsSPI=*/false);

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6664,7 +6664,7 @@ static void addUnavailableAttrs(ExtensionDecl *ext, NominalTypeDecl *nominal) {
66646664

66656665
auto attr = new (ctx) AvailableAttr(
66666666
SourceLoc(), SourceRange(),
6667-
AvailabilityDomain::forPlatform(available.getPlatform()),
6667+
AvailabilityDomain::forPlatform(available.getPlatform()), SourceLoc(),
66686668
AvailableAttr::Kind::Unavailable, available.getMessage(),
66696669
/*Rename=*/"", available.getIntroduced().value_or(noVersion),
66706670
SourceRange(), available.getDeprecated().value_or(noVersion),

lib/Serialization/Deserialization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5643,7 +5643,7 @@ DeclDeserializer::readAvailable_DECL_ATTR(SmallVectorImpl<uint64_t> &scratch,
56435643
}
56445644

56455645
auto attr = new (ctx)
5646-
AvailableAttr(SourceLoc(), SourceRange(), domain, kind, message, rename,
5646+
AvailableAttr(SourceLoc(), SourceRange(), domain, SourceLoc(), kind, message, rename,
56475647
Introduced, SourceRange(), Deprecated, SourceRange(),
56485648
Obsoleted, SourceRange(), isImplicit, isSPI);
56495649
return attr;

0 commit comments

Comments
 (0)