Skip to content

Commit 669930e

Browse files
authored
Merge pull request #77818 from tshortli/renamed-decl-requestification
2 parents 3e73210 + cd13d7d commit 669930e

17 files changed

+257
-186
lines changed

include/swift/AST/Attr.h

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,17 @@ class DeclAttribute : public AttributeBase {
147147
Value : 32
148148
);
149149

150-
SWIFT_INLINE_BITFIELD(AvailableAttr, DeclAttribute, 8+8+1+1,
150+
SWIFT_INLINE_BITFIELD(AvailableAttr, DeclAttribute, 8+8+1+1+1+1,
151151
/// A `PlatformKind` value.
152152
Platform : 8,
153153

154154
/// A `PlatformAgnosticAvailabilityKind` value.
155155
PlatformAgnostic : 8,
156156

157+
/// State storage for `RenamedDeclRequest`.
158+
HasComputedRenamedDecl : 1,
159+
HasRenamedDecl : 1,
160+
157161
/// Whether this attribute was spelled `@_spi_available`.
158162
IsSPI : 1,
159163

@@ -730,7 +734,7 @@ enum class PlatformAgnosticAvailabilityKind : uint8_t {
730734
class AvailableAttr : public DeclAttribute {
731735
public:
732736
AvailableAttr(SourceLoc AtLoc, SourceRange Range, PlatformKind Platform,
733-
StringRef Message, StringRef Rename, ValueDecl *RenameDecl,
737+
StringRef Message, StringRef Rename,
734738
const llvm::VersionTuple &Introduced,
735739
SourceRange IntroducedRange,
736740
const llvm::VersionTuple &Deprecated,
@@ -748,14 +752,13 @@ class AvailableAttr : public DeclAttribute {
748752
/// This should take the form of an operator, identifier, or full function
749753
/// name, optionally with a prefixed type, similar to the syntax used for
750754
/// the `NS_SWIFT_NAME` annotation in Objective-C.
755+
///
756+
/// \c ValueDecl::getRenamedDecl() can be used to look up the declaration
757+
/// referred to by this string. Note that this attribute can have a rename
758+
/// target that was provided directly when synthesized and therefore can have
759+
/// a rename decl even when this string is empty.
751760
const StringRef Rename;
752761

753-
/// The declaration referred to by \c Rename. Note that this is only set for
754-
/// deserialized attributes or inferred attributes from ObjectiveC code.
755-
/// \c ValueDecl::getRenamedDecl should be used to find the declaration
756-
/// corresponding to \c Rename.
757-
ValueDecl *RenameDecl;
758-
759762
/// Indicates when the symbol was introduced.
760763
const std::optional<llvm::VersionTuple> Introduced;
761764

@@ -849,11 +852,6 @@ class AvailableAttr : public DeclAttribute {
849852
llvm::VersionTuple Obsoleted
850853
= llvm::VersionTuple());
851854

852-
/// Create an AvailableAttr that indicates the given \p AsyncFunc should be
853-
/// preferentially used in async contexts
854-
static AvailableAttr *createForAlternative(ASTContext &C,
855-
AbstractFunctionDecl *AsyncFunc);
856-
857855
AvailableAttr *clone(ASTContext &C, bool implicit) const;
858856
AvailableAttr *clone(ASTContext &C) const {
859857
return clone(C, isImplicit());
@@ -862,6 +860,22 @@ class AvailableAttr : public DeclAttribute {
862860
static bool classof(const DeclAttribute *DA) {
863861
return DA->getKind() == DeclAttrKind::Available;
864862
}
863+
864+
bool hasCachedRenamedDecl() const {
865+
return Bits.AvailableAttr.HasRenamedDecl;
866+
}
867+
868+
private:
869+
friend class RenamedDeclRequest;
870+
871+
bool hasComputedRenamedDecl() const {
872+
return Bits.AvailableAttr.HasComputedRenamedDecl;
873+
}
874+
875+
void setComputedRenamedDecl(bool hasRenamedDecl) {
876+
Bits.AvailableAttr.HasComputedRenamedDecl = true;
877+
Bits.AvailableAttr.HasRenamedDecl = hasRenamedDecl;
878+
}
865879
};
866880

867881
/// Indicates that the given declaration is visible to Objective-C.

include/swift/AST/Decl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,6 +3262,15 @@ class ValueDecl : public Decl {
32623262
/// @_dynamicReplacement(for: ...), compute the original declaration
32633263
/// that this declaration dynamically replaces.
32643264
ValueDecl *getDynamicallyReplacedDecl() const;
3265+
3266+
/// Performs a request to look up the decl that this decl has been renamed to
3267+
/// if `attr` indicates that it has been renamed.
3268+
ValueDecl *getRenamedDecl(const AvailableAttr *attr) const;
3269+
3270+
/// Directly sets the renamed decl corresponding to `attr`. This should only
3271+
/// be used when synthesizing an `AvailableAttr`, before calling
3272+
/// `getRenamedDecl()`.
3273+
void setRenamedDecl(const AvailableAttr *attr, ValueDecl *renameDecl) const;
32653274
};
32663275

32673276
/// This is a common base class for declarations which declare a type.

include/swift/AST/TypeCheckRequests.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4085,8 +4085,9 @@ class ConditionalRequirementsRequest
40854085

40864086
class RenamedDeclRequest
40874087
: public SimpleRequest<RenamedDeclRequest,
4088-
ValueDecl *(const ValueDecl *, const AvailableAttr *),
4089-
RequestFlags::Cached> {
4088+
ValueDecl *(const ValueDecl *,
4089+
const AvailableAttr *),
4090+
RequestFlags::Cached | RequestFlags::SplitCached> {
40904091
public:
40914092
using SimpleRequest::SimpleRequest;
40924093

@@ -4098,6 +4099,8 @@ class RenamedDeclRequest
40984099

40994100
public:
41004101
bool isCached() const { return true; }
4102+
std::optional<ValueDecl *> getCachedResult() const;
4103+
void cacheResult(ValueDecl *value) const;
41014104
};
41024105

41034106
using AvailableAttrDeclPair = std::pair<const AvailableAttr *, const Decl *>;

lib/AST/Attr.cpp

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,8 @@ ParsedDeclAttrFilter::operator()(const DeclAttribute *Attr) const {
11131113
return Attr;
11141114
}
11151115

1116-
static void printAvailableAttr(const AvailableAttr *Attr, ASTPrinter &Printer,
1116+
static void printAvailableAttr(const Decl *D, const AvailableAttr *Attr,
1117+
ASTPrinter &Printer,
11171118
const PrintOptions &Options) {
11181119
if (Attr->isLanguageVersionSpecific())
11191120
Printer << "swift";
@@ -1138,17 +1139,19 @@ static void printAvailableAttr(const AvailableAttr *Attr, ASTPrinter &Printer,
11381139

11391140
if (!Attr->Rename.empty()) {
11401141
Printer << ", renamed: \"" << Attr->Rename << "\"";
1141-
} else if (Attr->RenameDecl) {
1142-
Printer << ", renamed: \"";
1143-
if (auto *Accessor = dyn_cast<AccessorDecl>(Attr->RenameDecl)) {
1144-
SmallString<32> Name;
1145-
llvm::raw_svector_ostream OS(Name);
1146-
Accessor->printUserFacingName(OS);
1147-
Printer << Name.str();
1148-
} else {
1149-
Printer << Attr->RenameDecl->getName();
1142+
} else if (auto *VD = dyn_cast<ValueDecl>(D)) {
1143+
if (auto *renamedDecl = VD->getRenamedDecl(Attr)) {
1144+
Printer << ", renamed: \"";
1145+
if (auto *Accessor = dyn_cast<AccessorDecl>(renamedDecl)) {
1146+
SmallString<32> Name;
1147+
llvm::raw_svector_ostream OS(Name);
1148+
Accessor->printUserFacingName(OS);
1149+
Printer << Name.str();
1150+
} else {
1151+
Printer << renamedDecl->getName();
1152+
}
1153+
Printer << "\"";
11501154
}
1151-
Printer << "\"";
11521155
}
11531156

11541157
// If there's no message, but this is specifically an imported
@@ -1365,7 +1368,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
13651368
Printer.printAttrName("@available");
13661369
}
13671370
Printer << "(";
1368-
printAvailableAttr(Attr, Printer, Options);
1371+
printAvailableAttr(D, Attr, Printer, Options);
13691372
Printer << ")";
13701373
break;
13711374
}
@@ -1464,7 +1467,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
14641467
Printer << "availability: ";
14651468
auto numAttrs = availAttrs.size();
14661469
if (numAttrs == 1) {
1467-
printAvailableAttr(availAttrs[0], Printer, Options);
1470+
printAvailableAttr(D, availAttrs[0], Printer, Options);
14681471
Printer << "; ";
14691472
} else {
14701473
SmallVector<const DeclAttribute *, 8> tmp(availAttrs.begin(),
@@ -2223,19 +2226,21 @@ Type RawLayoutAttr::getResolvedCountType(StructDecl *sd) const {
22232226

22242227
AvailableAttr::AvailableAttr(
22252228
SourceLoc AtLoc, SourceRange Range, PlatformKind Platform,
2226-
StringRef Message, StringRef Rename, ValueDecl *RenameDecl,
2229+
StringRef Message, StringRef Rename,
22272230
const llvm::VersionTuple &Introduced, SourceRange IntroducedRange,
22282231
const llvm::VersionTuple &Deprecated, SourceRange DeprecatedRange,
22292232
const llvm::VersionTuple &Obsoleted, SourceRange ObsoletedRange,
22302233
PlatformAgnosticAvailabilityKind PlatformAgnostic, bool Implicit,
22312234
bool IsSPI, bool IsForEmbedded)
22322235
: DeclAttribute(DeclAttrKind::Available, AtLoc, Range, Implicit),
2233-
Message(Message), Rename(Rename), RenameDecl(RenameDecl),
2236+
Message(Message), Rename(Rename),
22342237
INIT_VER_TUPLE(Introduced), IntroducedRange(IntroducedRange),
22352238
INIT_VER_TUPLE(Deprecated), DeprecatedRange(DeprecatedRange),
22362239
INIT_VER_TUPLE(Obsoleted), ObsoletedRange(ObsoletedRange) {
22372240
Bits.AvailableAttr.Platform = static_cast<uint8_t>(Platform);
22382241
Bits.AvailableAttr.PlatformAgnostic = static_cast<uint8_t>(PlatformAgnostic);
2242+
Bits.AvailableAttr.HasComputedRenamedDecl = false;
2243+
Bits.AvailableAttr.HasRenamedDecl = false;
22392244
Bits.AvailableAttr.IsSPI = IsSPI;
22402245

22412246
if (IsForEmbedded) {
@@ -2260,22 +2265,10 @@ AvailableAttr::createPlatformAgnostic(ASTContext &C,
22602265
assert(!Obsoleted.empty());
22612266
}
22622267
return new (C) AvailableAttr(
2263-
SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename, nullptr,
2264-
NoVersion, SourceRange(),
2265-
NoVersion, SourceRange(),
2266-
Obsoleted, SourceRange(),
2267-
Kind, /* isImplicit */ false, /*SPI*/false);
2268-
}
2269-
2270-
AvailableAttr *AvailableAttr::createForAlternative(
2271-
ASTContext &C, AbstractFunctionDecl *AsyncFunc) {
2272-
llvm::VersionTuple NoVersion;
2273-
return new (C) AvailableAttr(
2274-
SourceLoc(), SourceRange(), PlatformKind::none, "", "", AsyncFunc,
2275-
NoVersion, SourceRange(),
2276-
NoVersion, SourceRange(),
2277-
NoVersion, SourceRange(),
2278-
PlatformAgnosticAvailabilityKind::None, /*Implicit=*/true, /*SPI*/false);
2268+
SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename,
2269+
/*Introduced=*/NoVersion, SourceRange(), /*Deprecated=*/NoVersion,
2270+
SourceRange(), Obsoleted, SourceRange(), Kind, /*Implicit=*/false,
2271+
/*SPI=*/false);
22792272
}
22802273

22812274
bool AvailableAttr::isActivePlatform(const ASTContext &ctx) const {
@@ -2288,19 +2281,16 @@ bool BackDeployedAttr::isActivePlatform(const ASTContext &ctx,
22882281
}
22892282

22902283
AvailableAttr *AvailableAttr::clone(ASTContext &C, bool implicit) const {
2291-
return new (C) AvailableAttr(implicit ? SourceLoc() : AtLoc,
2292-
implicit ? SourceRange() : getRange(),
2293-
getPlatform(), Message, Rename, RenameDecl,
2294-
Introduced ? *Introduced : llvm::VersionTuple(),
2295-
implicit ? SourceRange() : IntroducedRange,
2296-
Deprecated ? *Deprecated : llvm::VersionTuple(),
2297-
implicit ? SourceRange() : DeprecatedRange,
2298-
Obsoleted ? *Obsoleted : llvm::VersionTuple(),
2299-
implicit ? SourceRange() : ObsoletedRange,
2300-
getPlatformAgnosticAvailability(),
2301-
implicit,
2302-
isSPI(),
2303-
isForEmbedded());
2284+
return new (C) AvailableAttr(
2285+
implicit ? SourceLoc() : AtLoc, implicit ? SourceRange() : getRange(),
2286+
getPlatform(), Message, Rename,
2287+
Introduced ? *Introduced : llvm::VersionTuple(),
2288+
implicit ? SourceRange() : IntroducedRange,
2289+
Deprecated ? *Deprecated : llvm::VersionTuple(),
2290+
implicit ? SourceRange() : DeprecatedRange,
2291+
Obsoleted ? *Obsoleted : llvm::VersionTuple(),
2292+
implicit ? SourceRange() : ObsoletedRange,
2293+
getPlatformAgnosticAvailability(), implicit, isSPI(), isForEmbedded());
23042294
}
23052295

23062296
std::optional<OriginallyDefinedInAttr::ActiveVersion>

lib/AST/Availability.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,10 @@ static AvailableAttr *createAvailableAttr(PlatformKind Platform,
183183
Inferred.Obsoleted.value_or(llvm::VersionTuple());
184184

185185
return new (Context)
186-
AvailableAttr(SourceLoc(), SourceRange(), Platform,
187-
Message, Rename, RenameDecl,
188-
Introduced, /*IntroducedRange=*/SourceRange(),
189-
Deprecated, /*DeprecatedRange=*/SourceRange(),
190-
Obsoleted, /*ObsoletedRange=*/SourceRange(),
191-
Inferred.PlatformAgnostic, /*Implicit=*/true,
192-
Inferred.IsSPI);
186+
AvailableAttr(SourceLoc(), SourceRange(), Platform, Message, Rename,
187+
Introduced, SourceRange(), Deprecated, SourceRange(),
188+
Obsoleted, SourceRange(), Inferred.PlatformAgnostic,
189+
/*Implicit=*/true, Inferred.IsSPI);
193190
}
194191

195192
void AvailabilityInference::applyInferredAvailableAttrs(
@@ -233,10 +230,8 @@ void AvailabilityInference::applyInferredAvailableAttrs(
233230
if (Message.empty() && !AvAttr->Message.empty())
234231
Message = AvAttr->Message;
235232

236-
if (Rename.empty() && !AvAttr->Rename.empty()) {
233+
if (Rename.empty() && !AvAttr->Rename.empty())
237234
Rename = AvAttr->Rename;
238-
RenameDecl = AvAttr->RenameDecl;
239-
}
240235
}
241236

242237
MergedAttrs.append(PendingAttrs);
@@ -248,15 +243,20 @@ void AvailabilityInference::applyInferredAvailableAttrs(
248243
}
249244

250245
DeclAttributes &Attrs = ToDecl->getAttrs();
246+
auto *ToValueDecl = dyn_cast<ValueDecl>(ToDecl);
251247

252248
// Create an availability attribute for each observed platform and add
253249
// to ToDecl.
254250
for (auto &Pair : Inferred) {
255251
auto *Attr = createAvailableAttr(Pair.first, Pair.second, Message,
256252
Rename, RenameDecl, Context);
257253

258-
if (Attr)
254+
if (Attr) {
255+
if (RenameDecl && ToValueDecl)
256+
ToValueDecl->setRenamedDecl(Attr, RenameDecl);
257+
259258
Attrs.add(Attr);
259+
}
260260
}
261261
}
262262

lib/AST/Decl.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4231,6 +4231,19 @@ bool ValueDecl::canInferObjCFromRequirement(ValueDecl *requirement) {
42314231
return false;
42324232
}
42334233

4234+
ValueDecl *ValueDecl::getRenamedDecl(const AvailableAttr *attr) const {
4235+
return evaluateOrDefault(getASTContext().evaluator,
4236+
RenamedDeclRequest{this, attr}, nullptr);
4237+
}
4238+
4239+
void ValueDecl::setRenamedDecl(const AvailableAttr *attr,
4240+
ValueDecl *renameDecl) const {
4241+
// This is only designed to be used with decls synthesized by ClangImporter.
4242+
assert(hasClangNode());
4243+
getASTContext().evaluator.cacheNonEmptyOutput(RenamedDeclRequest{this, attr},
4244+
std::move(renameDecl));
4245+
}
4246+
42344247
SourceLoc Decl::getAttributeInsertionLoc(bool forModifier) const {
42354248
// Some decls have a parent/child split where the introducer keyword is on the
42364249
// parent, but the attributes are on the children. If this is a child in such
@@ -9240,30 +9253,26 @@ AbstractFunctionDecl *AbstractFunctionDecl::getAsyncAlternative() const {
92409253
if (hasAsync())
92419254
return nullptr;
92429255

9243-
const AvailableAttr *avAttr = nullptr;
9256+
// Prefer the first availability attribute with no platform and a valid
9257+
// rename target, falling back to the first with a rename. Note that
9258+
// `getAttrs` is in reverse source order, so the last attribute is the
9259+
// first in source.
9260+
AbstractFunctionDecl *alternative = nullptr;
92449261
for (const auto *attr : getAttrs().getAttributes<AvailableAttr>()) {
9245-
// If there's an attribute with an already-resolved rename decl, use it
9246-
if (attr->RenameDecl) {
9247-
avAttr = attr;
9248-
break;
9249-
}
9262+
if (attr->isNoAsync())
9263+
continue;
9264+
9265+
if (attr->getPlatform() != PlatformKind::none && alternative != nullptr)
9266+
continue;
92509267

9251-
// Otherwise prefer the first availability attribute with no platform and
9252-
// rename parameter, falling back to the first with a rename. Note that
9253-
// `getAttrs` is in reverse source order, so the last attribute is the
9254-
// first in source
9255-
if (!attr->Rename.empty() &&
9256-
(attr->getPlatform() == PlatformKind::none || !avAttr) &&
9257-
!attr->isNoAsync()) {
9258-
avAttr = attr;
9268+
if (auto *renamedDecl = getRenamedDecl(attr)) {
9269+
if (auto *afd = dyn_cast<AbstractFunctionDecl>(renamedDecl)) {
9270+
if (afd->hasAsync())
9271+
alternative = afd;
9272+
}
92599273
}
92609274
}
92619275

9262-
auto *renamedDecl = evaluateOrDefault(
9263-
getASTContext().evaluator, RenamedDeclRequest{this, avAttr}, nullptr);
9264-
auto *alternative = dyn_cast_or_null<AbstractFunctionDecl>(renamedDecl);
9265-
if (!alternative || !alternative->hasAsync())
9266-
return nullptr;
92679276
return alternative;
92689277
}
92699278

0 commit comments

Comments
 (0)