Skip to content

Commit 05d342e

Browse files
committed
AST: Remove AvailableAttr::hasPlatform().
Use SemanticAvailableAttr::isPlatformSpecific() instead.
1 parent 5058534 commit 05d342e

File tree

4 files changed

+29
-35
lines changed

4 files changed

+29
-35
lines changed

include/swift/AST/Attr.h

-4
Original file line numberDiff line numberDiff line change
@@ -813,10 +813,6 @@ class AvailableAttr : public DeclAttribute {
813813
Bits.AvailableAttr.PlatformAgnostic);
814814
}
815815

816-
/// Returns true if the availability applies to a specific
817-
/// platform.
818-
bool hasPlatform() const { return getPlatform() != PlatformKind::none; }
819-
820816
/// Create an AvailableAttr that indicates specific availability
821817
/// for all platforms.
822818
static AvailableAttr *

lib/AST/Availability.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,9 @@ Decl::getSemanticAvailableAttrs(bool includeInactive) const {
468468
std::optional<SemanticAvailableAttr>
469469
Decl::getSemanticAvailableAttr(const AvailableAttr *attr) const {
470470
auto domainForAvailableAttr = [](const AvailableAttr *attr) {
471-
if (attr->hasPlatform())
472-
return AvailabilityDomain::forPlatform(attr->getPlatform());
471+
auto platform = attr->getPlatform();
472+
if (platform != PlatformKind::none)
473+
return AvailabilityDomain::forPlatform(platform);
473474

474475
switch (attr->getPlatformAgnosticAvailability()) {
475476
case PlatformAgnosticAvailabilityKind::Deprecated:

lib/Sema/TypeCheckAttr.cpp

+20-21
Original file line numberDiff line numberDiff line change
@@ -2276,16 +2276,19 @@ getSemanticAvailableRangeDeclAndAttr(const Decl *decl) {
22762276
return std::nullopt;
22772277
}
22782278

2279-
void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
2279+
void AttributeChecker::visitAvailableAttr(AvailableAttr *parsedAttr) {
22802280
if (Ctx.LangOpts.DisableAvailabilityChecking)
22812281
return;
22822282

2283-
// FIXME: This seems like it could be diagnosed during parsing instead.
2284-
while (attr->isSPI()) {
2285-
if (attr->hasPlatform() && attr->Introduced.has_value())
2286-
break;
2287-
diagnoseAndRemoveAttr(attr, diag::spi_available_malformed);
2288-
break;
2283+
auto attr = D->getSemanticAvailableAttr(parsedAttr);
2284+
if (!attr)
2285+
return;
2286+
2287+
if (attr->isSPI()) {
2288+
if (!attr->isPlatformSpecific() || !attr->getIntroduced().has_value()) {
2289+
diagnoseAndRemoveAttr(parsedAttr, diag::spi_available_malformed);
2290+
return;
2291+
}
22892292
}
22902293

22912294
if (attr->isNoAsync()) {
@@ -2312,7 +2315,7 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
23122315
// deinit's may not be unavailable from async contexts
23132316
if (isa<DestructorDecl>(D)) {
23142317
D->getASTContext().Diags.diagnose(
2315-
D->getLoc(), diag::invalid_decl_attribute, attr);
2318+
D->getLoc(), diag::invalid_decl_attribute, parsedAttr);
23162319
}
23172320
}
23182321

@@ -2323,32 +2326,28 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
23232326
return;
23242327

23252328
// The remaining diagnostics are only for attributes that are active.
2326-
auto semanticAttr = D->getSemanticAvailableAttr(attr);
2327-
if (!semanticAttr)
2328-
return;
2329-
2330-
if (!semanticAttr->isActive(Ctx))
2329+
if (!attr->isActive(Ctx))
23312330
return;
23322331

23332332
// Make sure there isn't a more specific attribute we should be using instead.
23342333
// getActiveAvailableAttrForCurrentPlatform() is O(N), so only do this if
23352334
// we're checking an iOS attribute while building for macCatalyst.
23362335
if (attr->getPlatform() == PlatformKind::iOS &&
23372336
isPlatformActive(PlatformKind::macCatalyst, Ctx.LangOpts)) {
2338-
if (semanticAttr != D->getActiveAvailableAttrForCurrentPlatform()) {
2337+
if (attr != D->getActiveAvailableAttrForCurrentPlatform()) {
23392338
return;
23402339
}
23412340
}
23422341

23432342
if (attr->getPlatform() == PlatformKind::iOS &&
23442343
isPlatformActive(PlatformKind::visionOS, Ctx.LangOpts)) {
2345-
if (semanticAttr != D->getActiveAvailableAttrForCurrentPlatform()) {
2344+
if (attr != D->getActiveAvailableAttrForCurrentPlatform()) {
23462345
return;
23472346
}
23482347
}
23492348

2350-
SourceLoc attrLoc = attr->getLocation();
2351-
auto versionAvailability = semanticAttr->getVersionAvailability(Ctx);
2349+
SourceLoc attrLoc = parsedAttr->getLocation();
2350+
auto versionAvailability = attr->getVersionAvailability(Ctx);
23522351
if (versionAvailability == AvailableVersionComparison::Obsoleted ||
23532352
versionAvailability == AvailableVersionComparison::Unavailable) {
23542353
if (auto cannotBeUnavailable =
@@ -2360,7 +2359,7 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
23602359
if (auto *PD = dyn_cast<ProtocolDecl>(DC)) {
23612360
if (auto *VD = dyn_cast<ValueDecl>(D)) {
23622361
if (VD->isProtocolRequirement() && !PD->isObjC()) {
2363-
diagnoseAndRemoveAttr(attr,
2362+
diagnoseAndRemoveAttr(parsedAttr,
23642363
diag::unavailable_method_non_objc_protocol);
23652364
return;
23662365
}
@@ -2370,15 +2369,15 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
23702369

23712370
// The remaining diagnostics are only for attributes with introduced versions
23722371
// for specific platforms.
2373-
if (!attr->hasPlatform() || !attr->Introduced.has_value())
2372+
if (!attr->isPlatformSpecific() || !attr->getIntroduced().has_value())
23742373
return;
23752374

23762375
// Find the innermost enclosing declaration with an availability
23772376
// range annotation and ensure that this attribute's available version range
23782377
// is fully contained within that declaration's range. If there is no such
23792378
// enclosing declaration, then there is nothing to check.
23802379
std::optional<AvailabilityRange> EnclosingAnnotatedRange;
2381-
AvailabilityRange AttrRange = semanticAttr->getIntroducedRange(Ctx);
2380+
AvailabilityRange AttrRange = attr->getIntroducedRange(Ctx);
23822381

23832382
if (auto *parent = getEnclosingDeclForDecl(D)) {
23842383
if (auto enclosingAvailable =
@@ -2399,7 +2398,7 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
23992398
limit = DiagnosticBehavior::Warning;
24002399
}
24012400
diagnose(D->isImplicit() ? enclosingDecl->getLoc()
2402-
: attr->getLocation(),
2401+
: parsedAttr->getLocation(),
24032402
diag::availability_decl_more_than_enclosing,
24042403
D->getDescriptiveKind())
24052404
.limitBehavior(limit);

lib/SymbolGraphGen/SymbolGraph.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -839,16 +839,14 @@ bool SymbolGraph::isImplicitlyPrivate(const Decl *D,
839839
return false;
840840
}
841841

842-
/// FIXME: This should use Decl::getUnavailableAttr() or similar.
842+
/// FIXME: [availability] This should use Decl::getUnavailableAttr() or similar.
843843
bool SymbolGraph::isUnconditionallyUnavailableOnAllPlatforms(const Decl *D) const {
844-
return llvm::any_of(D->getAttrs(), [](const auto *Attr) {
845-
if (const auto *AvAttr = dyn_cast<AvailableAttr>(Attr)) {
846-
return !AvAttr->hasPlatform()
847-
&& AvAttr->isUnconditionallyUnavailable();
848-
}
844+
for (auto Attr : D->getSemanticAvailableAttrs()) {
845+
if (!Attr.isPlatformSpecific() && Attr.isUnconditionallyUnavailable())
846+
return true;
847+
}
849848

850-
return false;
851-
});
849+
return false;
852850
}
853851

854852
/// Returns `true` if the symbol should be included as a node in the graph.

0 commit comments

Comments
 (0)