Skip to content

Commit 635ea34

Browse files
authored
Merge pull request swiftlang#78503 from tshortli/available-attr-creation-conveniences
AST: Introduce new conveniences for synthesizing AvailabilityAttrs
2 parents 4d4ba2d + 70a2363 commit 635ea34

File tree

6 files changed

+125
-95
lines changed

6 files changed

+125
-95
lines changed

include/swift/AST/Attr.h

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -813,14 +813,36 @@ class AvailableAttr : public DeclAttribute {
813813
Bits.AvailableAttr.PlatformAgnostic);
814814
}
815815

816-
/// Create an AvailableAttr that indicates specific availability
817-
/// for all platforms.
818-
static AvailableAttr *
819-
createPlatformAgnostic(ASTContext &C, StringRef Message, StringRef Rename = "",
820-
PlatformAgnosticAvailabilityKind Reason
821-
= PlatformAgnosticAvailabilityKind::Unavailable,
822-
llvm::VersionTuple Obsoleted
823-
= llvm::VersionTuple());
816+
/// Create an `AvailableAttr` that specifies universal unavailability, e.g.
817+
/// `@available(*, unavailable)`.
818+
static AvailableAttr *createUniversallyUnavailable(ASTContext &C,
819+
StringRef Message,
820+
StringRef Rename = "");
821+
822+
/// Create an `AvailableAttr` that specifies universal deprecation, e.g.
823+
/// `@available(*, deprecated)`.
824+
static AvailableAttr *createUniversallyDeprecated(ASTContext &C,
825+
StringRef Message,
826+
StringRef Rename = "");
827+
828+
/// Create an `AvailableAttr` that specifies unavailability in Swift, e.g.
829+
/// `@available(swift, unavailable)`.
830+
static AvailableAttr *createUnavailableInSwift(ASTContext &C,
831+
StringRef Message,
832+
StringRef Rename = "");
833+
834+
/// Create an `AvailableAttr` that specifies availability associated with
835+
/// Swift language modes, e.g. `@available(swift, obsoleted: 6)`.
836+
static AvailableAttr *createSwiftLanguageModeVersioned(
837+
ASTContext &C, StringRef Message, StringRef Rename,
838+
llvm::VersionTuple Introduced, llvm::VersionTuple Obsoleted);
839+
840+
/// Create an `AvailableAttr` that specifies versioned availability for a
841+
/// particular platform, e.g. `@available(macOS, introduced: 13)`.
842+
static AvailableAttr *createPlatformVersioned(
843+
ASTContext &C, PlatformKind Platform, StringRef Message, StringRef Rename,
844+
llvm::VersionTuple Introduced, llvm::VersionTuple Deprecated,
845+
llvm::VersionTuple Obsoleted);
824846

825847
AvailableAttr *clone(ASTContext &C, bool implicit) const;
826848
AvailableAttr *clone(ASTContext &C) const {

lib/AST/Attr.cpp

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,24 +2134,62 @@ AvailableAttr::AvailableAttr(
21342134

21352135
#undef INIT_VER_TUPLE
21362136

2137-
AvailableAttr *
2138-
AvailableAttr::createPlatformAgnostic(ASTContext &C,
2139-
StringRef Message,
2140-
StringRef Rename,
2141-
PlatformAgnosticAvailabilityKind Kind,
2142-
llvm::VersionTuple Obsoleted) {
2143-
assert(Kind != PlatformAgnosticAvailabilityKind::None);
2144-
llvm::VersionTuple NoVersion;
2145-
if (Kind == PlatformAgnosticAvailabilityKind::SwiftVersionSpecific) {
2146-
assert(!Obsoleted.empty());
2147-
}
2137+
AvailableAttr *AvailableAttr::createUniversallyUnavailable(ASTContext &C,
2138+
StringRef Message,
2139+
StringRef Rename) {
2140+
return new (C) AvailableAttr(
2141+
SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename,
2142+
/*Introduced=*/{}, SourceRange(), /*Deprecated=*/{}, SourceRange(),
2143+
/*Obsoleted=*/{}, SourceRange(),
2144+
PlatformAgnosticAvailabilityKind::Unavailable, /*Implicit=*/false,
2145+
/*SPI=*/false);
2146+
}
2147+
2148+
AvailableAttr *AvailableAttr::createUniversallyDeprecated(ASTContext &C,
2149+
StringRef Message,
2150+
StringRef Rename) {
2151+
return new (C) AvailableAttr(
2152+
SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename,
2153+
/*Introduced=*/{}, SourceRange(), /*Deprecated=*/{}, SourceRange(),
2154+
/*Obsoleted=*/{}, SourceRange(),
2155+
PlatformAgnosticAvailabilityKind::Deprecated, /*Implicit=*/false,
2156+
/*SPI=*/false);
2157+
}
2158+
2159+
AvailableAttr *AvailableAttr::createUnavailableInSwift(ASTContext &C,
2160+
StringRef Message,
2161+
StringRef Rename) {
21482162
return new (C) AvailableAttr(
21492163
SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename,
2150-
/*Introduced=*/NoVersion, SourceRange(), /*Deprecated=*/NoVersion,
2151-
SourceRange(), Obsoleted, SourceRange(), Kind, /*Implicit=*/false,
2164+
/*Introduced=*/{}, SourceRange(), /*Deprecated=*/{}, SourceRange(),
2165+
/*Obsoleted=*/{}, SourceRange(),
2166+
PlatformAgnosticAvailabilityKind::UnavailableInSwift, /*Implicit=*/false,
21522167
/*SPI=*/false);
21532168
}
21542169

2170+
AvailableAttr *AvailableAttr::createSwiftLanguageModeVersioned(
2171+
ASTContext &C, StringRef Message, StringRef Rename,
2172+
llvm::VersionTuple Introduced, llvm::VersionTuple Obsoleted) {
2173+
return new (C) AvailableAttr(
2174+
SourceLoc(), SourceRange(), PlatformKind::none, Message, Rename,
2175+
Introduced, SourceRange(), /*Deprecated=*/{}, SourceRange(), Obsoleted,
2176+
SourceRange(), PlatformAgnosticAvailabilityKind::SwiftVersionSpecific,
2177+
/*Implicit=*/false,
2178+
/*SPI=*/false);
2179+
}
2180+
2181+
AvailableAttr *AvailableAttr::createPlatformVersioned(
2182+
ASTContext &C, PlatformKind Platform, StringRef Message, StringRef Rename,
2183+
llvm::VersionTuple Introduced, llvm::VersionTuple Deprecated,
2184+
llvm::VersionTuple Obsoleted) {
2185+
return new (C) AvailableAttr(SourceLoc(), SourceRange(), Platform, Message,
2186+
Rename, Introduced, SourceRange(), Deprecated,
2187+
SourceRange(), Obsoleted, SourceRange(),
2188+
PlatformAgnosticAvailabilityKind::None,
2189+
/*Implicit=*/false,
2190+
/*SPI=*/false);
2191+
}
2192+
21552193
bool BackDeployedAttr::isActivePlatform(const ASTContext &ctx,
21562194
bool forTargetVariant) const {
21572195
return isPlatformActive(Platform, ctx.LangOpts, forTargetVariant);

lib/ClangImporter/ClangDerivedConformances.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,8 @@ void swift::conformToCxxSpanIfNeeded(ClangImporter::Implementation &impl,
12691269
if (!importedConstructor)
12701270
return;
12711271

1272-
auto attr = AvailableAttr::createPlatformAgnostic(importedConstructor->getASTContext(), "use 'init(_:)' instead.", "", PlatformAgnosticAvailabilityKind::Deprecated);
1272+
auto attr = AvailableAttr::createUniversallyDeprecated(
1273+
importedConstructor->getASTContext(), "use 'init(_:)' instead.", "");
12731274
importedConstructor->getAttrs().add(attr);
12741275

12751276
decl->addMember(importedConstructor);

lib/ClangImporter/ImportDecl.cpp

Lines changed: 38 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -558,18 +558,9 @@ static void applyAvailableAttribute(Decl *decl, AvailabilityRange &info,
558558
if (info.isAlwaysAvailable())
559559
return;
560560

561-
llvm::VersionTuple noVersion;
562-
auto AvAttr = new (C) AvailableAttr(
563-
SourceLoc(), SourceRange(), targetPlatform(C.LangOpts),
564-
/*Message=*/StringRef(),
565-
/*Rename=*/StringRef(), info.getRawMinimumVersion(),
566-
/*IntroducedRange=*/SourceRange(),
567-
/*Deprecated=*/noVersion,
568-
/*DeprecatedRange=*/SourceRange(),
569-
/*Obsoleted=*/noVersion,
570-
/*ObsoletedRange=*/SourceRange(), PlatformAgnosticAvailabilityKind::None,
571-
/*Implicit=*/false,
572-
/*SPI=*/false);
561+
auto AvAttr = AvailableAttr::createPlatformVersioned(
562+
C, targetPlatform(C.LangOpts), /*Message=*/"", /*Rename=*/"",
563+
info.getRawMinimumVersion(), /*Deprecated=*/{}, /*Obsoleted=*/{});
573564

574565
decl->getAttrs().add(AvAttr);
575566
}
@@ -1308,9 +1299,8 @@ namespace {
13081299
// "Raw" is the Objective-C name, which was never available in Swift.
13091300
// Variants within the active version are usually declarations that
13101301
// have been superseded, like the accessors of a property.
1311-
attr = AvailableAttr::createPlatformAgnostic(
1312-
ctx, /*Message*/StringRef(), ctx.AllocateCopy(renamed.str()),
1313-
PlatformAgnosticAvailabilityKind::UnavailableInSwift);
1302+
attr = AvailableAttr::createUnavailableInSwift(
1303+
ctx, /*Message*/ StringRef(), ctx.AllocateCopy(renamed.str()));
13141304
} else {
13151305
unsigned majorVersion = getVersion().majorVersionNumber();
13161306
unsigned minorVersion = getVersion().minorVersionNumber();
@@ -1323,26 +1313,19 @@ namespace {
13231313
(majorVersion == 4 && minorVersion < 2)
13241314
? llvm::VersionTuple(4, 2)
13251315
: llvm::VersionTuple(majorVersion + 1);
1326-
attr = AvailableAttr::createPlatformAgnostic(
1327-
ctx, /*Message*/StringRef(), ctx.AllocateCopy(renamed.str()),
1328-
PlatformAgnosticAvailabilityKind::SwiftVersionSpecific,
1329-
obsoletedVersion);
1316+
attr = AvailableAttr::createSwiftLanguageModeVersioned(
1317+
ctx, /*Message=*/"", ctx.AllocateCopy(renamed.str()),
1318+
/*Introduced=*/{}, obsoletedVersion);
13301319
} else {
13311320
// Future names are introduced in their future version.
13321321
assert(getVersion() > getActiveSwiftVersion());
13331322
llvm::VersionTuple introducedVersion =
13341323
(majorVersion == 4 && minorVersion == 2)
13351324
? llvm::VersionTuple(4, 2)
13361325
: llvm::VersionTuple(majorVersion);
1337-
attr = new (ctx) AvailableAttr(
1338-
SourceLoc(), SourceRange(), PlatformKind::none,
1339-
/*Message=*/StringRef(), ctx.AllocateCopy(renamed.str()),
1340-
/*Introduced=*/introducedVersion, SourceRange(),
1341-
/*Deprecated=*/llvm::VersionTuple(), SourceRange(),
1342-
/*Obsoleted=*/llvm::VersionTuple(), SourceRange(),
1343-
PlatformAgnosticAvailabilityKind::SwiftVersionSpecific,
1344-
/*Implicit=*/false,
1345-
/*SPI=*/false);
1326+
attr = AvailableAttr::createSwiftLanguageModeVersioned(
1327+
ctx, /*Message=*/"", ctx.AllocateCopy(renamed.str()),
1328+
introducedVersion, /*Obsoleted=*/{});
13461329
}
13471330
}
13481331

@@ -1529,10 +1512,8 @@ namespace {
15291512

15301513
// Make Objective-C's 'id' unavailable.
15311514
if (Impl.SwiftContext.LangOpts.EnableObjCInterop && isObjCId(Decl)) {
1532-
auto attr = AvailableAttr::createPlatformAgnostic(
1533-
Impl.SwiftContext,
1534-
"'id' is not available in Swift; use 'Any'", "",
1535-
PlatformAgnosticAvailabilityKind::UnavailableInSwift);
1515+
auto attr = AvailableAttr::createUnavailableInSwift(
1516+
Impl.SwiftContext, "'id' is not available in Swift; use 'Any'", "");
15361517
Result->getAttrs().add(attr);
15371518
}
15381519

@@ -2395,12 +2376,12 @@ namespace {
23952376
synthesizer.createDefaultConstructor(result);
23962377
ctors.push_back(defaultCtor);
23972378
if (cxxRecordDecl) {
2398-
auto attr = AvailableAttr::createPlatformAgnostic(
2379+
auto attr = AvailableAttr::createUniversallyDeprecated(
23992380
defaultCtor->getASTContext(),
24002381
"This zero-initializes the backing memory of the struct, which "
24012382
"is unsafe for some C++ structs. Consider adding an explicit "
24022383
"default initializer for this C++ struct.",
2403-
"", PlatformAgnosticAvailabilityKind::Deprecated);
2384+
"");
24042385
defaultCtor->getAttrs().add(attr);
24052386
}
24062387
}
@@ -2914,16 +2895,11 @@ namespace {
29142895
auto availability = Impl.SwiftContext.getSwift58Availability();
29152896
if (!availability.isAlwaysAvailable()) {
29162897
assert(availability.hasMinimumVersion());
2917-
auto AvAttr = new (Impl.SwiftContext)
2918-
AvailableAttr(SourceLoc(), SourceRange(),
2919-
targetPlatform(Impl.SwiftContext.LangOpts),
2920-
/*Message=*/"", /*Rename=*/"",
2921-
availability.getRawMinimumVersion(),
2922-
/*IntroducedRange=*/SourceRange(), {},
2923-
/*DeprecatedRange=*/SourceRange(), {},
2924-
/*ObsoletedRange=*/SourceRange(),
2925-
PlatformAgnosticAvailabilityKind::None,
2926-
/*Implicit=*/false, false);
2898+
auto AvAttr = AvailableAttr::createPlatformVersioned(
2899+
Impl.SwiftContext, targetPlatform(Impl.SwiftContext.LangOpts),
2900+
/*Message=*/"", /*Rename=*/"",
2901+
availability.getRawMinimumVersion(), /*Deprecated=*/{},
2902+
/*Obsoleted=*/{});
29272903
classDecl->getAttrs().add(AvAttr);
29282904
}
29292905
}
@@ -4423,7 +4399,7 @@ namespace {
44234399
decl, AccessLevel::Public, loc, name, loc, std::nullopt,
44244400
genericParamList, dc);
44254401

4426-
auto attr = AvailableAttr::createPlatformAgnostic(
4402+
auto attr = AvailableAttr::createUniversallyUnavailable(
44274403
Impl.SwiftContext, "Un-specialized class templates are not currently "
44284404
"supported. Please use a specialization of this "
44294405
"type.");
@@ -5393,8 +5369,8 @@ namespace {
53935369
message = "cannot find Swift declaration for this protocol";
53945370
else
53955371
llvm_unreachable("unknown bridged decl kind");
5396-
auto attr = AvailableAttr::createPlatformAgnostic(Impl.SwiftContext,
5397-
message);
5372+
auto attr = AvailableAttr::createUniversallyUnavailable(Impl.SwiftContext,
5373+
message);
53985374
VD->getAttrs().add(attr);
53995375
}
54005376

@@ -5447,7 +5423,7 @@ namespace {
54475423
addObjCAttribute(result,
54485424
Impl.importIdentifier(decl->getIdentifier()));
54495425
result->setImplicit();
5450-
auto attr = AvailableAttr::createPlatformAgnostic(
5426+
auto attr = AvailableAttr::createUniversallyUnavailable(
54515427
Impl.SwiftContext,
54525428
"This Objective-C protocol has only been forward-declared; "
54535429
"import its owning module to use it");
@@ -5602,7 +5578,8 @@ namespace {
56025578
auto result = createFakeClass(name, /* cacheResult */ true,
56035579
/* inheritFromNSObject */ true);
56045580
result->setImplicit();
5605-
auto attr = AvailableAttr::createPlatformAgnostic(Impl.SwiftContext,
5581+
auto attr = AvailableAttr::createUniversallyUnavailable(
5582+
Impl.SwiftContext,
56065583
"This Objective-C class has only been forward-declared; "
56075584
"import its owning module to use it");
56085585
result->getAttrs().add(attr);
@@ -6494,7 +6471,7 @@ SwiftDeclConverter::importOptionConstant(const clang::EnumConstantDecl *decl,
64946471
!CD->isUnavailable()) {
64956472
/// Create an AvailableAttr that indicates specific availability
64966473
/// for all platforms.
6497-
auto attr = AvailableAttr::createPlatformAgnostic(
6474+
auto attr = AvailableAttr::createUniversallyUnavailable(
64986475
Impl.SwiftContext, "use [] to construct an empty option set");
64996476
CD->getAttrs().add(attr);
65006477
}
@@ -7131,7 +7108,7 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
71317108
errorStr += objcMethod->getSelector().getAsString();
71327109
errorStr += ']';
71337110

7134-
auto attr = AvailableAttr::createPlatformAgnostic(
7111+
auto attr = AvailableAttr::createUniversallyUnavailable(
71357112
Impl.SwiftContext, Impl.SwiftContext.AllocateCopy(errorStr.str()));
71367113
ctor->getAttrs().add(attr);
71377114
continue;
@@ -8875,7 +8852,7 @@ void ClangImporter::Implementation::importAttributes(
88758852
//
88768853
if (auto unavailable = dyn_cast<clang::UnavailableAttr>(*AI)) {
88778854
auto Message = unavailable->getMessage();
8878-
auto attr = AvailableAttr::createPlatformAgnostic(C, Message);
8855+
auto attr = AvailableAttr::createUniversallyUnavailable(C, Message);
88798856
MappedDecl->getAttrs().add(attr);
88808857
AnyUnavailable = true;
88818858
continue;
@@ -8888,8 +8865,7 @@ void ClangImporter::Implementation::importAttributes(
88888865
//
88898866
if (auto unavailable_annot = dyn_cast<clang::AnnotateAttr>(*AI))
88908867
if (unavailable_annot->getAnnotation() == "swift1_unavailable") {
8891-
auto attr = AvailableAttr::createPlatformAgnostic(
8892-
C, "", "", PlatformAgnosticAvailabilityKind::UnavailableInSwift);
8868+
auto attr = AvailableAttr::createUnavailableInSwift(C, "", "");
88938869
MappedDecl->getAttrs().add(attr);
88948870
AnyUnavailable = true;
88958871
continue;
@@ -8902,8 +8878,7 @@ void ClangImporter::Implementation::importAttributes(
89028878
//
89038879
if (auto deprecated = dyn_cast<clang::DeprecatedAttr>(*AI)) {
89048880
auto Message = deprecated->getMessage();
8905-
auto attr = AvailableAttr::createPlatformAgnostic(C, Message, "",
8906-
PlatformAgnosticAvailabilityKind::Deprecated);
8881+
auto attr = AvailableAttr::createUniversallyDeprecated(C, Message, "");
89078882
MappedDecl->getAttrs().add(attr);
89088883
continue;
89098884
}
@@ -8925,9 +8900,8 @@ void ClangImporter::Implementation::importAttributes(
89258900
if (!replacement.empty())
89268901
swiftReplacement = getSwiftNameFromClangName(replacement);
89278902

8928-
auto attr = AvailableAttr::createPlatformAgnostic(
8929-
C, avail->getMessage(), swiftReplacement,
8930-
PlatformAgnosticAvailabilityKind::UnavailableInSwift);
8903+
auto attr = AvailableAttr::createUnavailableInSwift(
8904+
C, avail->getMessage(), swiftReplacement);
89318905
MappedDecl->getAttrs().add(attr);
89328906
AnyUnavailable = true;
89338907
continue;
@@ -9035,7 +9009,7 @@ void ClangImporter::Implementation::importAttributes(
90359009
if (auto ID = dyn_cast<clang::ObjCInterfaceDecl>(ClangDecl)) {
90369010
// Ban NSInvocation.
90379011
if (ID->getName() == "NSInvocation") {
9038-
auto attr = AvailableAttr::createPlatformAgnostic(C, "");
9012+
auto attr = AvailableAttr::createUniversallyUnavailable(C, "");
90399013
MappedDecl->getAttrs().add(attr);
90409014
return;
90419015
}
@@ -9068,8 +9042,8 @@ void ClangImporter::Implementation::importAttributes(
90689042
!FD->getAttr<clang::SwiftNameAttr>()) {
90699043
if (auto t = FD->getParamDecl(0)->getType()->getAs<clang::TypedefType>()){
90709044
if (isCFTypeDecl(t->getDecl())) {
9071-
auto attr = AvailableAttr::createPlatformAgnostic(C,
9072-
"Core Foundation objects are automatically memory managed");
9045+
auto attr = AvailableAttr::createUniversallyUnavailable(
9046+
C, "Core Foundation objects are automatically memory managed");
90739047
MappedDecl->getAttrs().add(attr);
90749048
return;
90759049
}
@@ -9757,8 +9731,8 @@ void ClangImporter::Implementation::
97579731
markUnavailable(ValueDecl *decl, StringRef unavailabilityMsgRef) {
97589732

97599733
unavailabilityMsgRef = SwiftContext.AllocateCopy(unavailabilityMsgRef);
9760-
auto ua = AvailableAttr::createPlatformAgnostic(SwiftContext,
9761-
unavailabilityMsgRef);
9734+
auto ua = AvailableAttr::createUniversallyUnavailable(SwiftContext,
9735+
unavailabilityMsgRef);
97629736
decl->getAttrs().add(ua);
97639737
}
97649738

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6672,13 +6672,8 @@ static void addUnavailableAttrs(ExtensionDecl *ext, NominalTypeDecl *nominal) {
66726672

66736673
// Add the blanket "unavailable".
66746674

6675-
auto attr = new (ctx) AvailableAttr(
6676-
SourceLoc(), SourceRange(), PlatformKind::none, /*Message*/ "",
6677-
/*Rename=*/"", /*Introduced=*/noVersion, SourceRange(),
6678-
/*Deprecated=*/noVersion, SourceRange(), /*Obsoleted=*/noVersion,
6679-
SourceRange(), PlatformAgnosticAvailabilityKind::Unavailable,
6680-
/*Implicit=*/false, /*SPI=*/false);
6681-
ext->getAttrs().add(attr);
6675+
ext->getAttrs().add(
6676+
AvailableAttr::createUniversallyUnavailable(ctx, /*Message=*/""));
66826677
}
66836678

66846679
ProtocolConformance *swift::deriveImplicitSendableConformance(

0 commit comments

Comments
 (0)