Skip to content

Commit 3e50a90

Browse files
committed
AST: Introduce Decl::getUnavailableAttr().
It replaces `DeclAttr::getUnavailable()` and `AvailableAttr::isUnavailable()` as the designated way to query for the attribute that makes a decl unavailable.
1 parent 43dfa6a commit 3e50a90

File tree

13 files changed

+84
-105
lines changed

13 files changed

+84
-105
lines changed

include/swift/AST/Attr.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -809,12 +809,6 @@ class AvailableAttr : public DeclAttribute {
809809
Bits.AvailableAttr.PlatformAgnostic);
810810
}
811811

812-
/// Determine if a given declaration should be considered unavailable given
813-
/// the current settings.
814-
///
815-
/// \returns The attribute responsible for making the declaration unavailable.
816-
static const AvailableAttr *isUnavailable(const Decl *D);
817-
818812
/// Returns true if the availability applies to a specific
819813
/// platform.
820814
bool hasPlatform() const { return getPlatform() != PlatformKind::none; }
@@ -2946,11 +2940,6 @@ class DeclAttributes {
29462940
findMostSpecificActivePlatform(const ASTContext &ctx,
29472941
bool ignoreAppExtensions = false) const;
29482942

2949-
/// Returns the first @available attribute that indicates
2950-
/// a declaration is unavailable, or null otherwise.
2951-
const AvailableAttr *getUnavailable(const ASTContext &ctx,
2952-
bool ignoreAppExtensions = false) const;
2953-
29542943
/// Returns the first @available attribute that indicates
29552944
/// a declaration is deprecated on all deployment targets, or null otherwise.
29562945
const AvailableAttr *getDeprecated(const ASTContext &ctx) const;

include/swift/AST/Decl.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
13901390
/// and its DeclContext does not.
13911391
bool isOutermostPrivateOrFilePrivateScope() const;
13921392

1393-
/// Returns true if the decl is always unavailable in this compilation
1393+
/// Returns true if the decl is always unavailable in the current compilation
13941394
/// context. For example, the decl could be marked explicitly unavailable on
13951395
/// either the current platform or in the current language mode. Returns false
13961396
/// for declarations that are only _potentially_ unavailable because of a
@@ -1399,7 +1399,13 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
13991399
///
14001400
/// Note that this query only considers the attributes that are attached
14011401
/// directly to this decl (or the extension it is declared in, if applicable).
1402-
bool isUnavailable() const;
1402+
bool isUnavailable() const { return getUnavailableAttr() != nullptr; }
1403+
1404+
/// If the decl is always unavailable in the current compilation
1405+
/// context, returns the attribute attached to the decl (or its parent
1406+
/// extension) that makes it unavailable.
1407+
const AvailableAttr *
1408+
getUnavailableAttr(bool ignoreAppExtensions = false) const;
14031409

14041410
/// Retrieve the @available attribute that provides the OS version range that
14051411
/// this declaration is available in.

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,8 +2150,6 @@ bool ShouldPrintChecker::shouldPrint(const Pattern *P,
21502150
}
21512151

21522152
bool isNonSendableExtension(const Decl *D) {
2153-
ASTContext &ctx = D->getASTContext();
2154-
21552153
const ExtensionDecl *ED = dyn_cast<ExtensionDecl>(D);
21562154
if (!ED || !ED->isUnavailable())
21572155
return false;

lib/AST/Attr.cpp

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -427,52 +427,6 @@ DeclAttributes::findMostSpecificActivePlatform(const ASTContext &ctx,
427427
return bestAttr;
428428
}
429429

430-
const AvailableAttr *
431-
DeclAttributes::getUnavailable(const ASTContext &ctx,
432-
bool ignoreAppExtensions) const {
433-
const AvailableAttr *conditional = nullptr;
434-
const AvailableAttr *bestActive =
435-
findMostSpecificActivePlatform(ctx, ignoreAppExtensions);
436-
437-
for (auto Attr : *this)
438-
if (auto AvAttr = dyn_cast<AvailableAttr>(Attr)) {
439-
if (AvAttr->isInvalid())
440-
continue;
441-
442-
// If this is a platform-specific attribute and it isn't the most
443-
// specific attribute for the current platform, we're done.
444-
if (AvAttr->hasPlatform() &&
445-
(!bestActive || AvAttr != bestActive))
446-
continue;
447-
448-
// If this attribute doesn't apply to the active platform, we're done.
449-
if (!AvAttr->isActivePlatform(ctx) &&
450-
!AvAttr->isLanguageVersionSpecific() &&
451-
!AvAttr->isPackageDescriptionVersionSpecific())
452-
continue;
453-
454-
if (ignoreAppExtensions &&
455-
isApplicationExtensionPlatform(AvAttr->getPlatform()))
456-
continue;
457-
458-
// Unconditional unavailable.
459-
if (AvAttr->isUnconditionallyUnavailable())
460-
return AvAttr;
461-
462-
switch (AvAttr->getVersionAvailability(ctx)) {
463-
case AvailableVersionComparison::Available:
464-
case AvailableVersionComparison::PotentiallyUnavailable:
465-
break;
466-
467-
case AvailableVersionComparison::Obsoleted:
468-
case AvailableVersionComparison::Unavailable:
469-
conditional = AvAttr;
470-
break;
471-
}
472-
}
473-
return conditional;
474-
}
475-
476430
const AvailableAttr *
477431
DeclAttributes::getDeprecated(const ASTContext &ctx) const {
478432
const AvailableAttr *conditional = nullptr;
@@ -2440,25 +2394,6 @@ AvailableVersionComparison AvailableAttr::getVersionAvailability(
24402394
return AvailableVersionComparison::Available;
24412395
}
24422396

2443-
const AvailableAttr *AvailableAttr::isUnavailable(const Decl *D) {
2444-
ASTContext &ctx = D->getASTContext();
2445-
if (auto attr = D->getAttrs().getUnavailable(ctx))
2446-
return attr;
2447-
2448-
// If D is an extension member, check if the extension is unavailable.
2449-
//
2450-
// Skip decls imported from Clang, they could be associated to the wrong
2451-
// extension and inherit undesired unavailability. The ClangImporter
2452-
// associates Objective-C protocol members to the first category where the
2453-
// protocol is directly or indirectly adopted, no matter its availability
2454-
// and the availability of other categories. rdar://problem/53956555
2455-
if (!D->getClangNode())
2456-
if (auto ext = dyn_cast<ExtensionDecl>(D->getDeclContext()))
2457-
return AvailableAttr::isUnavailable(ext);
2458-
2459-
return nullptr;
2460-
}
2461-
24622397
SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range,
24632398
TrailingWhereClause *clause, bool exported,
24642399
SpecializationKind kind,

lib/AST/Availability.cpp

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,14 +486,71 @@ bool Decl::isAvailableAsSPI() const {
486486
return AvailabilityInference::isAvailableAsSPI(this);
487487
}
488488

489-
bool Decl::isUnavailable() const { return AvailableAttr::isUnavailable(this); }
489+
static const AvailableAttr *
490+
getDeclUnavailableAttr(const Decl *D, bool ignoreAppExtensions) {
491+
auto &ctx = D->getASTContext();
492+
auto attrs = D->getAttrs();
493+
const AvailableAttr *result = nullptr;
494+
const AvailableAttr *bestActive =
495+
attrs.findMostSpecificActivePlatform(ctx, ignoreAppExtensions);
496+
497+
for (auto attr :
498+
D->getAttrs().getAttributes<AvailableAttr, /*AllowInvalid=*/false>()) {
499+
// If this is a platform-specific attribute and it isn't the most
500+
// specific attribute for the current platform, we're done.
501+
if (attr->hasPlatform() && (!bestActive || attr != bestActive))
502+
continue;
503+
504+
// If this attribute doesn't apply to the active platform, we're done.
505+
if (!attr->isActivePlatform(ctx) && !attr->isLanguageVersionSpecific() &&
506+
!attr->isPackageDescriptionVersionSpecific())
507+
continue;
508+
509+
if (ignoreAppExtensions &&
510+
isApplicationExtensionPlatform(attr->getPlatform()))
511+
continue;
512+
513+
// Unconditional unavailable.
514+
if (attr->isUnconditionallyUnavailable())
515+
return attr;
516+
517+
switch (attr->getVersionAvailability(ctx)) {
518+
case AvailableVersionComparison::Available:
519+
case AvailableVersionComparison::PotentiallyUnavailable:
520+
break;
521+
522+
case AvailableVersionComparison::Obsoleted:
523+
case AvailableVersionComparison::Unavailable:
524+
result = attr;
525+
break;
526+
}
527+
}
528+
return result;
529+
}
530+
531+
const AvailableAttr *Decl::getUnavailableAttr(bool ignoreAppExtensions) const {
532+
if (auto attr = getDeclUnavailableAttr(this, ignoreAppExtensions))
533+
return attr;
534+
535+
// If D is an extension member, check if the extension is unavailable.
536+
//
537+
// Skip decls imported from Clang, they could be associated to the wrong
538+
// extension and inherit undesired unavailability. The ClangImporter
539+
// associates Objective-C protocol members to the first category where the
540+
// protocol is directly or indirectly adopted, no matter its availability
541+
// and the availability of other categories. rdar://problem/53956555
542+
if (!getClangNode())
543+
if (auto ext = dyn_cast<ExtensionDecl>(getDeclContext()))
544+
return ext->getUnavailableAttr(ignoreAppExtensions);
545+
546+
return nullptr;
547+
}
490548

491549
std::optional<AvailableAttrDeclPair>
492550
SemanticUnavailableAttrRequest::evaluate(Evaluator &evaluator, const Decl *decl,
493551
bool ignoreAppExtensions) const {
494552
// Directly marked unavailable.
495-
if (auto attr = decl->getAttrs().getUnavailable(decl->getASTContext(),
496-
ignoreAppExtensions))
553+
if (auto attr = decl->getUnavailableAttr(ignoreAppExtensions))
497554
return std::make_pair(attr, decl);
498555

499556
if (auto *parent =

lib/AST/AvailabilityContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ bool AvailabilityContext::PlatformInfo::constrainWith(const Decl *decl) {
5757
if (auto range = AvailabilityInference::annotatedAvailableRange(decl))
5858
isConstrained |= constrainRange(Range, *range);
5959

60-
if (auto *attr = decl->getAttrs().getUnavailable(ctx)) {
60+
if (auto *attr = decl->getUnavailableAttr()) {
6161
isConstrained |= constrainUnavailability(attr->getPlatform());
6262
isConstrained |=
6363
CONSTRAIN_BOOL(IsUnavailableInEmbedded, attr->isForEmbedded());

lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,14 +911,13 @@ static bool eliminateSwitchDispatchOnUnavailableElements(
911911
if (!ED->hasCasesUnavailableDuringLowering())
912912
return false;
913913

914-
ASTContext &ctx = BB.getModule().getASTContext();
915914
SILLocation Loc = SWI->getLoc();
916915
bool DidRemoveUnavailableCase = false;
917916

918917
SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 4> NewCaseBBs;
919918
for (unsigned i : range(SWI.getNumCases())) {
920919
auto CaseBB = SWI.getCase(i);
921-
auto availableAtr = CaseBB.first->getAttrs().getUnavailable(ctx);
920+
auto availableAtr = CaseBB.first->getUnavailableAttr();
922921

923922
if (availableAtr && availableAtr->isUnconditionallyUnavailable()) {
924923
// Mark the basic block as potentially unreachable.

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ static bool isInsideCompatibleUnavailableDeclaration(
370370

371371
const AvailableAttr *
372372
ExportContext::shouldDiagnoseDeclAsUnavailable(const Decl *D) const {
373-
auto attr = AvailableAttr::isUnavailable(D);
373+
auto attr = D->getUnavailableAttr();
374374
if (!attr)
375375
return nullptr;
376376

@@ -2929,11 +2929,10 @@ static bool diagnoseExplicitUnavailability(const ValueDecl *D, SourceRange R,
29292929
const ExportContext &Where,
29302930
const Expr *call,
29312931
DeclAvailabilityFlags Flags) {
2932-
return diagnoseExplicitUnavailability(D, R, Where, Flags,
2933-
[=](InFlightDiagnostic &diag) {
2934-
fixItAvailableAttrRename(diag, R, D, AvailableAttr::isUnavailable(D),
2935-
call);
2936-
});
2932+
return diagnoseExplicitUnavailability(
2933+
D, R, Where, Flags, [=](InFlightDiagnostic &diag) {
2934+
fixItAvailableAttrRename(diag, R, D, D->getUnavailableAttr(), call);
2935+
});
29372936
}
29382937

29392938
/// Represents common information needed to emit diagnostics about explicitly
@@ -3110,7 +3109,7 @@ swift::getUnsatisfiedAvailabilityConstraint(
31103109
if (isa<GenericTypeParamDecl>(decl))
31113110
return std::nullopt;
31123111

3113-
if (auto attr = AvailableAttr::isUnavailable(decl)) {
3112+
if (auto attr = decl->getUnavailableAttr()) {
31143113
if (isInsideCompatibleUnavailableDeclaration(decl, availabilityContext,
31153114
attr))
31163115
return std::nullopt;
@@ -4043,7 +4042,7 @@ bool ExprAvailabilityWalker::diagnoseDeclRefAvailability(
40434042
if (D->getModuleContext()->isBuiltinModule())
40444043
return false;
40454044

4046-
if (auto *attr = AvailableAttr::isUnavailable(D)) {
4045+
if (auto *attr = D->getUnavailableAttr()) {
40474046
if (diagnoseIncDecRemoval(D, R, attr))
40484047
return true;
40494048
if (isa_and_nonnull<ApplyExpr>(call) &&

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,8 +3314,6 @@ class ObjCImplementationChecker {
33143314
if (!VD)
33153315
return;
33163316

3317-
ASTContext &ctx = VD->getASTContext();
3318-
33193317
// Also skip overrides, unless they override an unavailable decl, which
33203318
// makes them not formally overrides anymore.
33213319
if (VD->getOverriddenDecl() && !VD->getOverriddenDecl()->isUnavailable())

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ bool swift::isOverrideBasedOnType(const ValueDecl *decl, Type declTy,
242242

243243
static bool isUnavailableInAllVersions(ValueDecl *decl) {
244244
ASTContext &ctx = decl->getASTContext();
245-
auto *attr = decl->getAttrs().getUnavailable(ctx);
245+
auto *attr = decl->getUnavailableAttr();
246246

247247
if (!attr)
248248
return false;
@@ -1946,9 +1946,8 @@ checkOverrideUnavailability(ValueDecl *override, ValueDecl *base) {
19461946
}
19471947
}
19481948

1949-
auto &ctx = override->getASTContext();
1950-
auto *baseUnavailableAttr = base->getAttrs().getUnavailable(ctx);
1951-
auto *overrideUnavailableAttr = override->getAttrs().getUnavailable(ctx);
1949+
auto *baseUnavailableAttr = base->getUnavailableAttr();
1950+
auto *overrideUnavailableAttr = override->getUnavailableAttr();
19521951

19531952
if (baseUnavailableAttr && !overrideUnavailableAttr)
19541953
return {OverrideUnavailabilityStatus::BaseUnavailable, baseUnavailableAttr};

0 commit comments

Comments
 (0)