Skip to content

Commit 00aae6e

Browse files
committed
AST: Return SemanticAvailableAttr from Decl::getUnavailableAttr().
1 parent 055a9ec commit 00aae6e

10 files changed

+77
-89
lines changed

include/swift/AST/Attr.h

+3
Original file line numberDiff line numberDiff line change
@@ -3244,6 +3244,9 @@ class SemanticAvailableAttr final {
32443244
return getDomain().isPackageDescription() && isVersionSpecific();
32453245
}
32463246

3247+
/// Whether this attribute was spelled `@_unavailableInEmbedded`.
3248+
bool isEmbeddedSpecific() const { return attr->isForEmbedded(); }
3249+
32473250
/// Returns the active version from the AST context corresponding to
32483251
/// the available kind. For example, this will return the effective language
32493252
/// version for swift version-specific availability kind, PackageDescription

include/swift/AST/Decl.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1443,12 +1443,12 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
14431443
///
14441444
/// Note that this query only considers the attributes that are attached
14451445
/// directly to this decl (or the extension it is declared in, if applicable).
1446-
bool isUnavailable() const { return getUnavailableAttr() != nullptr; }
1446+
bool isUnavailable() const { return getUnavailableAttr().has_value(); }
14471447

14481448
/// If the decl is always unavailable in the current compilation
14491449
/// context, returns the attribute attached to the decl (or its parent
14501450
/// extension) that makes it unavailable.
1451-
const AvailableAttr *
1451+
std::optional<SemanticAvailableAttr>
14521452
getUnavailableAttr(bool ignoreAppExtensions = false) const;
14531453

14541454
/// Returns true if the decl is effectively always unavailable in the current

lib/AST/Availability.cpp

+12-15
Original file line numberDiff line numberDiff line change
@@ -610,45 +610,43 @@ bool Decl::isUnavailableInCurrentSwiftVersion() const {
610610
return false;
611611
}
612612

613-
static const AvailableAttr *
613+
std::optional<SemanticAvailableAttr>
614614
getDeclUnavailableAttr(const Decl *D, bool ignoreAppExtensions) {
615615
auto &ctx = D->getASTContext();
616-
const AvailableAttr *result = nullptr;
616+
std::optional<SemanticAvailableAttr> result;
617617
auto bestActive =
618618
D->getActiveAvailableAttrForCurrentPlatform(ignoreAppExtensions);
619619

620-
for (auto semanticAttr :
621-
D->getSemanticAvailableAttrs(/*includingInactive=*/false)) {
622-
auto attr = semanticAttr.getParsedAttr();
623-
620+
for (auto attr : D->getSemanticAvailableAttrs(/*includingInactive=*/false)) {
624621
// If this is a platform-specific attribute and it isn't the most
625622
// specific attribute for the current platform, we're done.
626-
if (attr->hasPlatform() && (!bestActive || semanticAttr != bestActive))
623+
if (attr.isPlatformSpecific() && (!bestActive || attr != bestActive))
627624
continue;
628625

629626
if (ignoreAppExtensions &&
630-
isApplicationExtensionPlatform(attr->getPlatform()))
627+
isApplicationExtensionPlatform(attr.getPlatform()))
631628
continue;
632629

633630
// Unconditional unavailable.
634-
if (attr->isUnconditionallyUnavailable())
631+
if (attr.isUnconditionallyUnavailable())
635632
return attr;
636633

637-
switch (semanticAttr.getVersionAvailability(ctx)) {
634+
switch (attr.getVersionAvailability(ctx)) {
638635
case AvailableVersionComparison::Available:
639636
case AvailableVersionComparison::PotentiallyUnavailable:
640637
break;
641638

642639
case AvailableVersionComparison::Obsoleted:
643640
case AvailableVersionComparison::Unavailable:
644-
result = attr;
641+
result.emplace(attr);
645642
break;
646643
}
647644
}
648645
return result;
649646
}
650647

651-
const AvailableAttr *Decl::getUnavailableAttr(bool ignoreAppExtensions) const {
648+
std::optional<SemanticAvailableAttr>
649+
Decl::getUnavailableAttr(bool ignoreAppExtensions) const {
652650
if (auto attr = getDeclUnavailableAttr(this, ignoreAppExtensions))
653651
return attr;
654652

@@ -663,16 +661,15 @@ const AvailableAttr *Decl::getUnavailableAttr(bool ignoreAppExtensions) const {
663661
if (auto ext = dyn_cast<ExtensionDecl>(getDeclContext()))
664662
return ext->getUnavailableAttr(ignoreAppExtensions);
665663

666-
return nullptr;
664+
return std::nullopt;
667665
}
668666

669667
static bool isDeclCompletelyUnavailable(const Decl *decl) {
670668
// Don't trust unavailability on declarations from clang modules.
671669
if (isa<ClangModuleUnit>(decl->getDeclContext()->getModuleScopeContext()))
672670
return false;
673671

674-
auto *unavailableAttr =
675-
decl->getUnavailableAttr(/*ignoreAppExtensions=*/true);
672+
auto unavailableAttr = decl->getUnavailableAttr(/*ignoreAppExtensions=*/true);
676673
if (!unavailableAttr)
677674
return false;
678675

lib/AST/AvailabilityContext.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ 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->getUnavailableAttr()) {
60+
if (auto attr = decl->getUnavailableAttr()) {
6161
isConstrained |= constrainUnavailability(attr->getPlatform());
6262
isConstrained |=
63-
CONSTRAIN_BOOL(IsUnavailableInEmbedded, attr->isForEmbedded());
63+
CONSTRAIN_BOOL(IsUnavailableInEmbedded, attr->isEmbeddedSpecific());
6464
}
6565

6666
isConstrained |= CONSTRAIN_BOOL(IsDeprecated, decl->isDeprecated());

lib/Sema/TypeCheckAttr.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -4833,10 +4833,10 @@ void AttributeChecker::checkBackDeployedAttrs(
48334833
// Find the attribute that makes the declaration unavailable.
48344834
const Decl *attrDecl = D;
48354835
do {
4836-
if (auto *unavailableAttr = attrDecl->getUnavailableAttr()) {
4837-
diagnose(unavailableAttr->AtLoc,
4836+
if (auto unavailableAttr = attrDecl->getUnavailableAttr()) {
4837+
diagnose(unavailableAttr->getParsedAttr()->AtLoc,
48384838
diag::availability_marked_unavailable, VD)
4839-
.highlight(unavailableAttr->getRange());
4839+
.highlight(unavailableAttr->getParsedAttr()->getRange());
48404840
break;
48414841
}
48424842

lib/Sema/TypeCheckAvailability.cpp

+41-50
Original file line numberDiff line numberDiff line change
@@ -345,39 +345,39 @@ static bool computeContainedByDeploymentTarget(AvailabilityScope *scope,
345345
/// unconditional unavailable declaration for the same platform.
346346
static bool isInsideCompatibleUnavailableDeclaration(
347347
const Decl *D, AvailabilityContext availabilityContext,
348-
const AvailableAttr *attr) {
348+
const SemanticAvailableAttr &attr) {
349349
auto contextPlatform = availabilityContext.getUnavailablePlatformKind();
350350
if (!contextPlatform)
351351
return false;
352352

353-
if (!attr->isUnconditionallyUnavailable())
353+
if (!attr.isUnconditionallyUnavailable())
354354
return false;
355355

356356
// Refuse calling universally unavailable functions from unavailable code,
357357
// but allow the use of types.
358-
PlatformKind declPlatform = attr->getPlatform();
359-
if (declPlatform == PlatformKind::none && !attr->isForEmbedded() &&
358+
PlatformKind declPlatform = attr.getPlatform();
359+
if (declPlatform == PlatformKind::none && !attr.isEmbeddedSpecific() &&
360360
!isa<TypeDecl>(D) && !isa<ExtensionDecl>(D))
361361
return false;
362362

363363
// @_unavailableInEmbedded declarations may be used in contexts that are
364364
// also @_unavailableInEmbedded.
365-
if (attr->isForEmbedded())
365+
if (attr.isEmbeddedSpecific())
366366
return availabilityContext.isUnavailableInEmbedded();
367367

368368
return (*contextPlatform == PlatformKind::none ||
369369
*contextPlatform == declPlatform ||
370370
inheritsAvailabilityFromPlatform(declPlatform, *contextPlatform));
371371
}
372372

373-
const AvailableAttr *
373+
std::optional<SemanticAvailableAttr>
374374
ExportContext::shouldDiagnoseDeclAsUnavailable(const Decl *D) const {
375375
auto attr = D->getUnavailableAttr();
376376
if (!attr)
377-
return nullptr;
377+
return std::nullopt;
378378

379-
if (isInsideCompatibleUnavailableDeclaration(D, Availability, attr))
380-
return nullptr;
379+
if (isInsideCompatibleUnavailableDeclaration(D, Availability, *attr))
380+
return std::nullopt;
381381

382382
return attr;
383383
}
@@ -2996,7 +2996,9 @@ static bool diagnoseExplicitUnavailability(const ValueDecl *D, SourceRange R,
29962996
DeclAvailabilityFlags Flags) {
29972997
return diagnoseExplicitUnavailability(
29982998
D, R, Where, Flags, [=](InFlightDiagnostic &diag) {
2999-
fixItAvailableAttrRename(diag, R, D, D->getUnavailableAttr(), call);
2999+
auto attr = D->getUnavailableAttr();
3000+
assert(attr);
3001+
fixItAvailableAttrRename(diag, R, D, attr->getParsedAttr(), call);
30003002
});
30013003
}
30023004

@@ -3019,20 +3021,18 @@ class UnavailabilityDiagnosticInfo {
30193021

30203022
private:
30213023
Status DiagnosticStatus;
3022-
const AvailableAttr *Attr;
3023-
AvailabilityDomain Domain;
3024+
SemanticAvailableAttr Attr;
30243025

30253026
public:
3026-
UnavailabilityDiagnosticInfo(Status status, const AvailableAttr *attr,
3027-
AvailabilityDomain domain)
3028-
: DiagnosticStatus(status), Attr(attr), Domain(domain) {
3029-
assert(attr);
3030-
};
3027+
UnavailabilityDiagnosticInfo(Status status, const SemanticAvailableAttr &attr)
3028+
: DiagnosticStatus(status), Attr(attr) {};
30313029

30323030
Status getStatus() const { return DiagnosticStatus; }
3033-
const AvailableAttr *getAttr() const { return Attr; }
3034-
AvailabilityDomain getDomain() const { return Domain; }
3035-
StringRef getDomainName() const { return Domain.getNameForDiagnostics(); }
3031+
const AvailableAttr *getAttr() const { return Attr.getParsedAttr(); }
3032+
AvailabilityDomain getDomain() const { return Attr.getDomain(); }
3033+
StringRef getDomainName() const {
3034+
return getDomain().getNameForDiagnostics();
3035+
}
30363036

30373037
bool shouldHideDomainNameInUnversionedDiagnostics() const {
30383038
switch (getDomain().getKind()) {
@@ -3057,39 +3057,32 @@ class UnavailabilityDiagnosticInfo {
30573057
static std::optional<UnavailabilityDiagnosticInfo>
30583058
getExplicitUnavailabilityDiagnosticInfo(const Decl *decl,
30593059
const ExportContext &where) {
3060-
auto *attr = where.shouldDiagnoseDeclAsUnavailable(decl);
3060+
auto attr = where.shouldDiagnoseDeclAsUnavailable(decl);
30613061
if (!attr)
30623062
return std::nullopt;
30633063

3064-
auto semanticAttr = decl->getSemanticAvailableAttr(attr);
3065-
if (!semanticAttr)
3066-
return std::nullopt;
3067-
30683064
ASTContext &ctx = decl->getASTContext();
30693065

3070-
switch (semanticAttr->getVersionAvailability(ctx)) {
3066+
switch (attr->getVersionAvailability(ctx)) {
30713067
case AvailableVersionComparison::Available:
30723068
case AvailableVersionComparison::PotentiallyUnavailable:
30733069
llvm_unreachable("These aren't considered unavailable");
30743070

30753071
case AvailableVersionComparison::Unavailable:
3076-
if ((semanticAttr->isSwiftLanguageModeSpecific() ||
3077-
semanticAttr->isPackageDescriptionVersionSpecific()) &&
3078-
attr->Introduced.has_value()) {
3072+
if ((attr->isSwiftLanguageModeSpecific() ||
3073+
attr->isPackageDescriptionVersionSpecific()) &&
3074+
attr->getIntroduced()) {
30793075
return UnavailabilityDiagnosticInfo(
3080-
UnavailabilityDiagnosticInfo::Status::IntroducedInVersion, attr,
3081-
semanticAttr->getDomain());
3076+
UnavailabilityDiagnosticInfo::Status::IntroducedInVersion, *attr);
30823077
} else {
30833078
return UnavailabilityDiagnosticInfo(
3084-
UnavailabilityDiagnosticInfo::Status::AlwaysUnavailable, attr,
3085-
semanticAttr->getDomain());
3079+
UnavailabilityDiagnosticInfo::Status::AlwaysUnavailable, *attr);
30863080
}
30873081
break;
30883082

30893083
case AvailableVersionComparison::Obsoleted:
30903084
return UnavailabilityDiagnosticInfo(
3091-
UnavailabilityDiagnosticInfo::Status::Obsoleted, attr,
3092-
semanticAttr->getDomain());
3085+
UnavailabilityDiagnosticInfo::Status::Obsoleted, *attr);
30933086
}
30943087
}
30953088

@@ -3161,29 +3154,26 @@ swift::getUnsatisfiedAvailabilityConstraint(
31613154
return std::nullopt;
31623155

31633156
if (auto attr = decl->getUnavailableAttr()) {
3164-
auto semanticAttr = decl->getSemanticAvailableAttr(attr);
3165-
if (!semanticAttr)
3166-
return std::nullopt;
3167-
31683157
if (isInsideCompatibleUnavailableDeclaration(decl, availabilityContext,
3169-
attr))
3158+
*attr))
31703159
return std::nullopt;
31713160

3172-
switch (semanticAttr->getVersionAvailability(ctx)) {
3161+
auto parsedAttr = attr->getParsedAttr();
3162+
switch (attr->getVersionAvailability(ctx)) {
31733163
case AvailableVersionComparison::Available:
31743164
case AvailableVersionComparison::PotentiallyUnavailable:
31753165
llvm_unreachable("Decl should be unavailable");
31763166

31773167
case AvailableVersionComparison::Unavailable:
3178-
if ((semanticAttr->isSwiftLanguageModeSpecific() ||
3179-
semanticAttr->isPackageDescriptionVersionSpecific()) &&
3180-
attr->Introduced.has_value())
3181-
return AvailabilityConstraint::forRequiresVersion(attr);
3168+
if ((attr->isSwiftLanguageModeSpecific() ||
3169+
attr->isPackageDescriptionVersionSpecific()) &&
3170+
attr->getIntroduced().has_value())
3171+
return AvailabilityConstraint::forRequiresVersion(parsedAttr);
31823172

3183-
return AvailabilityConstraint::forAlwaysUnavailable(attr);
3173+
return AvailabilityConstraint::forAlwaysUnavailable(parsedAttr);
31843174

31853175
case AvailableVersionComparison::Obsoleted:
3186-
return AvailabilityConstraint::forObsoleted(attr);
3176+
return AvailabilityConstraint::forObsoleted(parsedAttr);
31873177
}
31883178
}
31893179

@@ -4131,11 +4121,12 @@ bool ExprAvailabilityWalker::diagnoseDeclRefAvailability(
41314121
if (D->getModuleContext()->isBuiltinModule())
41324122
return false;
41334123

4134-
if (auto *attr = D->getUnavailableAttr()) {
4135-
if (diagnoseIncDecRemoval(D, R, attr))
4124+
if (auto attr = D->getUnavailableAttr()) {
4125+
auto parsedAttr = attr->getParsedAttr();
4126+
if (diagnoseIncDecRemoval(D, R, parsedAttr))
41364127
return true;
41374128
if (isa_and_nonnull<ApplyExpr>(call) &&
4138-
diagnoseMemoryLayoutMigration(D, R, attr, cast<ApplyExpr>(call)))
4129+
diagnoseMemoryLayoutMigration(D, R, parsedAttr, cast<ApplyExpr>(call)))
41394130
return true;
41404131
}
41414132

lib/Sema/TypeCheckAvailability.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#ifndef SWIFT_SEMA_TYPE_CHECK_AVAILABILITY_H
1414
#define SWIFT_SEMA_TYPE_CHECK_AVAILABILITY_H
1515

16-
#include "swift/AST/AttrKind.h"
16+
#include "swift/AST/Attr.h"
1717
#include "swift/AST/AvailabilityConstraint.h"
1818
#include "swift/AST/AvailabilityContext.h"
1919
#include "swift/AST/DeclContext.h"
@@ -26,7 +26,6 @@
2626

2727
namespace swift {
2828
class ApplyExpr;
29-
class AvailableAttr;
3029
class Expr;
3130
class ClosureExpr;
3231
class InFlightDiagnostic;
@@ -198,7 +197,8 @@ class ExportContext {
198197
/// is not also unavailable in the same way, then this returns the specific
199198
/// `@available` attribute that makes the decl unavailable. Otherwise, returns
200199
/// nullptr.
201-
const AvailableAttr *shouldDiagnoseDeclAsUnavailable(const Decl *decl) const;
200+
std::optional<SemanticAvailableAttr>
201+
shouldDiagnoseDeclAsUnavailable(const Decl *decl) const;
202202
};
203203

204204
/// Check if a declaration is exported as part of a module's external interface.

lib/Sema/TypeCheckDeclOverride.cpp

+6-9
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,14 @@ bool swift::isOverrideBasedOnType(const ValueDecl *decl, Type declTy,
242242

243243
static bool isUnavailableInAllVersions(ValueDecl *decl) {
244244
ASTContext &ctx = decl->getASTContext();
245-
auto *attr = decl->getUnavailableAttr();
245+
auto attr = decl->getUnavailableAttr();
246246
if (!attr)
247247
return false;
248248

249-
auto semanticAttr = decl->getSemanticAvailableAttr(attr);
250-
if (!semanticAttr)
251-
return false;
252-
253249
if (attr->isUnconditionallyUnavailable())
254250
return true;
255251

256-
return semanticAttr->getVersionAvailability(ctx) ==
252+
return attr->getVersionAvailability(ctx) ==
257253
AvailableVersionComparison::Unavailable;
258254
}
259255

@@ -1942,11 +1938,12 @@ checkOverrideUnavailability(ValueDecl *override, ValueDecl *base) {
19421938
}
19431939
}
19441940

1945-
auto *baseUnavailableAttr = base->getUnavailableAttr();
1946-
auto *overrideUnavailableAttr = override->getUnavailableAttr();
1941+
auto baseUnavailableAttr = base->getUnavailableAttr();
1942+
auto overrideUnavailableAttr = override->getUnavailableAttr();
19471943

19481944
if (baseUnavailableAttr && !overrideUnavailableAttr)
1949-
return {OverrideUnavailabilityStatus::BaseUnavailable, baseUnavailableAttr};
1945+
return {OverrideUnavailabilityStatus::BaseUnavailable,
1946+
baseUnavailableAttr->getParsedAttr()};
19501947

19511948
return {OverrideUnavailabilityStatus::Compatible, nullptr};
19521949
}

0 commit comments

Comments
 (0)