Skip to content

Commit 9fe7b3b

Browse files
Merge pull request #83591 from swiftlang/jepa-rebranch
Manually merge remote-tracking branch 'origin/main' into rebranch
2 parents 0b40a82 + ece73d8 commit 9fe7b3b

File tree

12 files changed

+134
-87
lines changed

12 files changed

+134
-87
lines changed

include/swift/AST/AvailabilityQuery.h

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,31 +46,50 @@ class AvailabilityQuery final {
4646
bool unavailable;
4747

4848
AvailabilityQuery(AvailabilityDomain domain, ResultKind kind,
49-
bool isUnavailable,
5049
const std::optional<AvailabilityRange> &primaryRange,
5150
const std::optional<AvailabilityRange> &variantRange)
5251
: domain(domain), primaryRange(primaryRange), variantRange(variantRange),
53-
kind(kind), unavailable(isUnavailable) {};
52+
kind(kind), unavailable(false) {};
5453

5554
public:
5655
/// Returns an `AvailabilityQuery` for a query that evaluates to true or
5756
/// false at compile-time.
58-
static AvailabilityQuery constant(AvailabilityDomain domain,
59-
bool isUnavailable, bool value) {
57+
static AvailabilityQuery constant(AvailabilityDomain domain, bool value) {
6058
return AvailabilityQuery(
6159
domain, value ? ResultKind::ConstTrue : ResultKind::ConstFalse,
62-
isUnavailable, std::nullopt, std::nullopt);
60+
std::nullopt, std::nullopt);
61+
}
62+
63+
/// Returns an `AvailabilityQuery` for a query that evaluates to true or
64+
/// false at compile-time in the universal availability domain.
65+
static AvailabilityQuery universallyConstant(bool value) {
66+
return AvailabilityQuery(AvailabilityDomain::forUniversal(),
67+
value ? ResultKind::ConstTrue
68+
: ResultKind::ConstFalse,
69+
std::nullopt, std::nullopt);
6370
}
6471

6572
/// Returns an `AvailabilityQuery` for a query that must be evaluated at
6673
/// runtime with the given arguments, which may be zero, one, or two version
6774
/// tuples that should be passed to the query function.
6875
static AvailabilityQuery
69-
dynamic(AvailabilityDomain domain, bool isUnavailable,
76+
dynamic(AvailabilityDomain domain,
7077
const std::optional<AvailabilityRange> &primaryRange,
7178
const std::optional<AvailabilityRange> &variantRange) {
72-
return AvailabilityQuery(domain, ResultKind::Dynamic, isUnavailable,
73-
primaryRange, variantRange);
79+
return AvailabilityQuery(domain, ResultKind::Dynamic, primaryRange,
80+
variantRange);
81+
}
82+
83+
/// Returns a copy of the `AvailabilityQuery` that has been modified to
84+
/// represent an `if #unavailable` query if `isUnavailability` is true, or an
85+
/// `if #available` query otherwise.
86+
AvailabilityQuery asUnavailable(bool isUnavailability) const {
87+
if (isUnavailability != unavailable) {
88+
AvailabilityQuery copy = *this;
89+
copy.unavailable = isUnavailability;
90+
return copy;
91+
}
92+
return *this;
7493
}
7594

7695
/// Returns the domain that the query applies to.

include/swift/AST/Decl.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "swift/AST/AccessScope.h"
2121
#include "swift/AST/Attr.h"
22+
#include "swift/AST/AvailabilityQuery.h"
2223
#include "swift/AST/AvailabilityRange.h"
2324
#include "swift/AST/CaptureInfo.h"
2425
#include "swift/AST/ClangNode.h"
@@ -3694,39 +3695,36 @@ class OpaqueTypeDecl final :
36943695
return false;
36953696
}
36963697

3697-
using AvailabilityCondition = std::pair<VersionRange, bool>;
3698-
36993698
class ConditionallyAvailableSubstitutions final
3700-
: private llvm::TrailingObjects<
3701-
ConditionallyAvailableSubstitutions,
3702-
AvailabilityCondition> {
3699+
: private llvm::TrailingObjects<ConditionallyAvailableSubstitutions,
3700+
AvailabilityQuery> {
37033701
friend TrailingObjects;
37043702

3705-
unsigned NumAvailabilityConditions;
3703+
unsigned NumAvailabilityQueries;
37063704

37073705
SubstitutionMap Substitutions;
37083706

37093707
/// A type with limited availability described by the provided set
37103708
/// of availability conditions (with `and` relationship).
37113709
ConditionallyAvailableSubstitutions(
3712-
ArrayRef<AvailabilityCondition> availabilityContext,
3710+
ArrayRef<AvailabilityQuery> availabilityQueries,
37133711
SubstitutionMap substitutions)
3714-
: NumAvailabilityConditions(availabilityContext.size()),
3712+
: NumAvailabilityQueries(availabilityQueries.size()),
37153713
Substitutions(substitutions) {
3716-
assert(!availabilityContext.empty());
3717-
std::uninitialized_copy(availabilityContext.begin(),
3718-
availabilityContext.end(), getTrailingObjects());
3714+
assert(!availabilityQueries.empty());
3715+
std::uninitialized_copy(availabilityQueries.begin(),
3716+
availabilityQueries.end(), getTrailingObjects());
37193717
}
37203718

37213719
public:
3722-
ArrayRef<AvailabilityCondition> getAvailability() const {
3723-
return getTrailingObjects(NumAvailabilityConditions);
3720+
ArrayRef<AvailabilityQuery> getAvailabilityQueries() const {
3721+
return getTrailingObjects(NumAvailabilityQueries);
37243722
}
37253723

37263724
SubstitutionMap getSubstitutions() const { return Substitutions; }
37273725

37283726
static ConditionallyAvailableSubstitutions *
3729-
get(ASTContext &ctx, ArrayRef<AvailabilityCondition> availabilityContext,
3727+
get(ASTContext &ctx, ArrayRef<AvailabilityQuery> availabilityContext,
37303728
SubstitutionMap substitutions);
37313729
};
37323730
};

lib/AST/AvailabilityScopeBuilder.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -816,8 +816,7 @@ class AvailabilityScopeBuilder : private ASTWalker {
816816

817817
AvailabilityQuery buildAvailabilityQuery(
818818
const SemanticAvailabilitySpec spec,
819-
const std::optional<SemanticAvailabilitySpec> &variantSpec,
820-
bool isUnavailability) {
819+
const std::optional<SemanticAvailabilitySpec> &variantSpec) {
821820
auto domain = spec.getDomain();
822821

823822
// Variant availability specfications are only supported for platform
@@ -850,37 +849,34 @@ class AvailabilityScopeBuilder : private ASTWalker {
850849
// If all of the specs that matched are '*', then the query trivially
851850
// evaluates to "true" at compile time.
852851
if (!variantRange)
853-
return AvailabilityQuery::constant(domain, isUnavailability, true);
852+
return AvailabilityQuery::constant(domain, true);
854853

855854
// Otherwise, generate a dynamic query for the variant spec. For example,
856855
// when compiling zippered for macOS, this should generate a query that
857856
// just checks the iOS version at runtime:
858857
//
859858
// if #available(iOS 18, *) { ... }
860859
//
861-
return AvailabilityQuery::dynamic(variantSpec->getDomain(),
862-
isUnavailability, primaryRange,
860+
return AvailabilityQuery::dynamic(variantSpec->getDomain(), primaryRange,
863861
variantRange);
864862

865863
case AvailabilityDomain::Kind::Platform:
866864
// Platform checks are always dynamic. The SIL optimizer is responsible
867865
// eliminating these checks when it can prove that they can never fail
868866
// (due to the deployment target). We can't perform that analysis here
869867
// because it may depend on inlining.
870-
return AvailabilityQuery::dynamic(domain, isUnavailability, primaryRange,
871-
variantRange);
868+
return AvailabilityQuery::dynamic(domain, primaryRange, variantRange);
872869
case AvailabilityDomain::Kind::Custom:
873870
auto customDomain = domain.getCustomDomain();
874871
ASSERT(customDomain);
875872

876873
switch (customDomain->getKind()) {
877874
case CustomAvailabilityDomain::Kind::Enabled:
878-
return AvailabilityQuery::constant(domain, isUnavailability, true);
875+
return AvailabilityQuery::constant(domain, true);
879876
case CustomAvailabilityDomain::Kind::Disabled:
880-
return AvailabilityQuery::constant(domain, isUnavailability, false);
877+
return AvailabilityQuery::constant(domain, false);
881878
case CustomAvailabilityDomain::Kind::Dynamic:
882-
return AvailabilityQuery::dynamic(domain, isUnavailability,
883-
primaryRange, variantRange);
879+
return AvailabilityQuery::dynamic(domain, primaryRange, variantRange);
884880
}
885881
}
886882
}
@@ -1053,8 +1049,9 @@ class AvailabilityScopeBuilder : private ASTWalker {
10531049
? bestActiveSpecForQuery(query, /*ForTargetVariant*/ true)
10541050
: std::nullopt;
10551051

1056-
query->setAvailabilityQuery(buildAvailabilityQuery(
1057-
*spec, variantSpec, query->isUnavailability()));
1052+
query->setAvailabilityQuery(
1053+
buildAvailabilityQuery(*spec, variantSpec)
1054+
.asUnavailable(query->isUnavailability()));
10581055

10591056
// Wildcards are expected to be "useless". There may be other specs in
10601057
// this query that are useful when compiling for other platforms.

lib/AST/Decl.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10879,14 +10879,12 @@ void OpaqueTypeDecl::setConditionallyAvailableSubstitutions(
1087910879

1088010880
OpaqueTypeDecl::ConditionallyAvailableSubstitutions *
1088110881
OpaqueTypeDecl::ConditionallyAvailableSubstitutions::get(
10882-
ASTContext &ctx,
10883-
ArrayRef<AvailabilityCondition> availabilityContext,
10882+
ASTContext &ctx, ArrayRef<AvailabilityQuery> availabilityQueries,
1088410883
SubstitutionMap substitutions) {
10885-
auto size =
10886-
totalSizeToAlloc<AvailabilityCondition>(availabilityContext.size());
10884+
auto size = totalSizeToAlloc<AvailabilityQuery>(availabilityQueries.size());
1088710885
auto mem = ctx.Allocate(size, alignof(ConditionallyAvailableSubstitutions));
1088810886
return new (mem)
10889-
ConditionallyAvailableSubstitutions(availabilityContext, substitutions);
10887+
ConditionallyAvailableSubstitutions(availabilityQueries, substitutions);
1089010888
}
1089110889

1089210890
bool AbstractFunctionDecl::hasInlinableBodyText() const {

lib/AST/SwiftNameTranslation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ bool swift::cxx_translation::isObjCxxOnly(const clang::Decl *D,
271271
// requirements and the language options to check if we should actually
272272
// consider the module to have ObjC constructs.
273273
const auto &langOpts = D->getASTContext().getLangOpts();
274+
// TODO: have a reasonable guess for headers specified via
275+
// `-import-objc-header`.
276+
if (!D->hasOwningModule())
277+
return false;
274278
auto clangModule = D->getOwningModule()->getTopLevelModule();
275279
bool requiresObjC = false;
276280
for (auto req : clangModule->Requirements)

lib/IRGen/GenMeta.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,30 +2704,30 @@ namespace {
27042704

27052705
// Emit a #available condition check, if it's `false` -
27062706
// jump to the next conditionally available type.
2707-
auto conditions = underlyingTy->getAvailability();
2707+
auto queries = underlyingTy->getAvailabilityQueries();
27082708

27092709
SmallVector<llvm::BasicBlock *, 4> conditionBlocks;
2710-
for (unsigned condIndex : indices(conditions)) {
2710+
for (unsigned queryIndex : indices(queries)) {
27112711
// cond-<type_idx>-<cond_index>
27122712
conditionBlocks.push_back(IGF.createBasicBlock(
2713-
"cond-" + llvm::utostr(i) + "-" + llvm::utostr(condIndex)));
2713+
"cond-" + llvm::utostr(i) + "-" + llvm::utostr(queryIndex)));
27142714
}
27152715

27162716
// Jump to the first condition.
27172717
IGF.Builder.CreateBr(conditionBlocks.front());
27182718

2719-
for (unsigned condIndex : indices(conditions)) {
2720-
const auto &condition = conditions[condIndex];
2719+
for (unsigned queryIndex : indices(queries)) {
2720+
const auto &query = queries[queryIndex];
27212721

2722-
assert(condition.first.hasLowerEndpoint());
2722+
assert(query.getPrimaryArgument());
27232723

2724-
bool isUnavailability = condition.second;
2725-
auto version = condition.first.getLowerEndpoint();
2724+
bool isUnavailability = query.isUnavailability();
2725+
auto version = query.getPrimaryArgument().value();
27262726
auto *major = getInt32Constant(version.getMajor());
27272727
auto *minor = getInt32Constant(version.getMinor());
27282728
auto *patch = getInt32Constant(version.getSubminor());
27292729

2730-
IGF.Builder.emitBlock(conditionBlocks[condIndex]);
2730+
IGF.Builder.emitBlock(conditionBlocks[queryIndex]);
27312731

27322732
auto isAtLeast =
27332733
IGF.emitTargetOSVersionAtLeastCall(major, minor, patch);
@@ -2742,9 +2742,9 @@ namespace {
27422742
IGF.Builder.CreateXor(success, IGF.Builder.getIntN(1, -1));
27432743
}
27442744

2745-
auto nextCondOrRet = condIndex == conditions.size() - 1
2745+
auto nextCondOrRet = queryIndex == queries.size() - 1
27462746
? returnTypeBB
2747-
: conditionBlocks[condIndex + 1];
2747+
: conditionBlocks[queryIndex + 1];
27482748

27492749
IGF.Builder.CreateCondBr(success, nextCondOrRet,
27502750
conditionalTypes[i + 1]);
@@ -2761,8 +2761,8 @@ namespace {
27612761
IGF.Builder.emitBlock(conditionalTypes.back());
27622762
auto universal = substitutionSet.back();
27632763

2764-
assert(universal->getAvailability().size() == 1 &&
2765-
universal->getAvailability()[0].first.isAll());
2764+
assert(universal->getAvailabilityQueries().size() == 1 &&
2765+
universal->getAvailabilityQueries()[0].isConstant());
27662766

27672767
IGF.Builder.CreateRet(
27682768
getResultValue(IGF, genericEnv, universal->getSubstitutions()));

lib/SILGen/SILGenAvailability.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,13 @@ getAvailabilityQueryForBackDeployment(AbstractFunctionDecl *AFD) {
131131
variantRange = variantAttrAndRange->second;
132132

133133
return AvailabilityQuery::dynamic(attr->getAvailabilityDomain(),
134-
/*isUnavailable=*/false, primaryRange,
135-
variantRange);
134+
primaryRange, variantRange);
136135
}
137136

138137
if (auto primaryAttrAndRange = AFD->getBackDeployedAttrAndRange(ctx))
139138
return AvailabilityQuery::dynamic(
140139
primaryAttrAndRange->first->getAvailabilityDomain(),
141-
/*isUnavailable=*/false, primaryAttrAndRange->second, std::nullopt);
140+
primaryAttrAndRange->second, std::nullopt);
142141

143142
return std::nullopt;
144143
}

lib/Sema/DerivedConformance/DerivedConformanceRawRepresentable.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,7 @@ struct RuntimeVersionCheck {
218218
// This won't be filled in by TypeCheckAvailability because we have
219219
// invalid SourceLocs in this area of the AST.
220220
availableInfo->setAvailabilityQuery(AvailabilityQuery::dynamic(
221-
domain, /*isUnavailable=*/false, AvailabilityRange(getVersionRange()),
222-
std::nullopt));
221+
domain, AvailabilityRange(getVersionRange()), std::nullopt));
223222

224223
// earlyReturnBody = "{ return nil }"
225224
auto earlyReturn = new (C) FailStmt(SourceLoc(), SourceLoc());

lib/Sema/MiscDiagnostics.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3721,8 +3721,6 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
37213721
// There is no clear winner here since there are candidates within
37223722
// limited availability contexts.
37233723
void finalizeOpaque(const Candidate &universallyAvailable) {
3724-
using AvailabilityCondition = OpaqueTypeDecl::AvailabilityCondition;
3725-
37263724
SmallVector<OpaqueTypeDecl::ConditionallyAvailableSubstitutions *, 4>
37273725
conditionalSubstitutions;
37283726
SubstitutionMap universalSubstMap = std::get<1>(universallyAvailable);
@@ -3735,7 +3733,7 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
37353733
continue;
37363734

37373735
unsigned neverAvailableCount = 0, alwaysAvailableCount = 0;
3738-
SmallVector<AvailabilityCondition, 4> conditions;
3736+
SmallVector<AvailabilityQuery, 4> queries;
37393737

37403738
for (const auto &elt : stmt->getCond()) {
37413739
auto availabilityQuery = elt.getAvailability()->getAvailabilityQuery();
@@ -3762,11 +3760,7 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
37623760
auto domain = availabilityQuery->getDomain();
37633761
ASSERT(domain.isPlatform());
37643762

3765-
auto availabilityRange = availabilityQuery->getPrimaryRange();
3766-
ASSERT(availabilityRange);
3767-
3768-
conditions.push_back({availabilityRange->getRawVersionRange(),
3769-
availabilityQuery->isUnavailability()});
3763+
queries.push_back(*availabilityQuery);
37703764
}
37713765

37723766
// If there were any conditions that were always false, then this
@@ -3782,18 +3776,18 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
37823776
break;
37833777
}
37843778

3785-
ASSERT(conditions.size() > 0);
3779+
ASSERT(queries.size() > 0);
37863780

37873781
conditionalSubstitutions.push_back(
37883782
OpaqueTypeDecl::ConditionallyAvailableSubstitutions::get(
3789-
Ctx, conditions,
3783+
Ctx, queries,
37903784
std::get<1>(candidate).mapReplacementTypesOutOfContext()));
37913785
}
37923786

37933787
// Add universally available choice as the last one.
37943788
conditionalSubstitutions.push_back(
37953789
OpaqueTypeDecl::ConditionallyAvailableSubstitutions::get(
3796-
Ctx, {{VersionRange::all(), /*unavailable=*/false}},
3790+
Ctx, {AvailabilityQuery::universallyConstant(true)},
37973791
universalSubstMap.mapReplacementTypesOutOfContext()));
37983792

37993793
OpaqueDecl->setConditionallyAvailableSubstitutions(

0 commit comments

Comments
 (0)