Skip to content

Commit f6ab0ae

Browse files
authored
Merge pull request #41612 from tshortli/back-deploy-diagnose-decls
Update @_backDeploy ABI semantics and diagnose invalid declarations
2 parents 7abc8a4 + 3047cd3 commit f6ab0ae

18 files changed

+538
-225
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ DECL_ATTR(exclusivity, Exclusivity,
718718
128)
719719

720720
DECL_ATTR(_backDeploy, BackDeploy,
721-
OnAbstractFunction |
721+
OnAbstractFunction | OnAccessor | OnSubscript | OnVar |
722722
AllowMultipleAttributes | LongAttribute | UserInaccessible |
723723
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIBreakingToRemove,
724724
129)

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,11 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
825825
/// This function won't consider the parent context to get the information.
826826
Optional<llvm::VersionTuple> getIntroducedOSVersion(PlatformKind Kind) const;
827827

828+
/// Returns the OS version in which the decl became ABI as specified by the
829+
/// @_backDeploy attribute.
830+
Optional<llvm::VersionTuple>
831+
getBackDeployBeforeOSVersion(PlatformKind Kind) const;
832+
828833
/// Returns the starting location of the entire declaration.
829834
SourceLoc getStartLoc() const { return getSourceRange().Start; }
830835

include/swift/AST/DiagnosticsSema.def

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,26 +1599,12 @@ WARNING(option_set_zero_constant,none,
15991599
NOTE(option_set_empty_set_init,none,
16001600
"use [] to silence this warning", ())
16011601

1602-
// FIXME(backDeploy): Refactor to share with back deployment attr
1603-
ERROR(originally_defined_in_dupe_platform,none,
1604-
"duplicate version number for platform %0", (StringRef))
1605-
16061602
ERROR(originally_definedin_topleve_decl,none,
16071603
"@%0 is only applicable to top-level decl", (StringRef))
16081604

1609-
// FIXME(backDeploy): Refactor to share with back deployment attr
1610-
ERROR(originally_definedin_need_available,none,
1611-
"need @available attribute for @%0", (StringRef))
1612-
16131605
ERROR(originally_definedin_must_not_before_available_version,none,
16141606
"symbols are moved to the current module before they were available in the OSs", (StringRef))
16151607

1616-
// FIXME(backDeploy): Refactor to share with back deployment attr
1617-
WARNING(originally_defined_in_on_non_public,
1618-
none, "@%0 does not have any effect on "
1619-
"%select{private|fileprivate|internal|%error|%error}1 declarations",
1620-
(StringRef, AccessLevel))
1621-
16221608
// Alignment attribute
16231609
ERROR(alignment_not_power_of_two,none,
16241610
"alignment value must be a power of two", ())
@@ -3139,10 +3125,28 @@ ERROR(attr_not_on_variadic_parameters,none,
31393125
"'%0' must not be used on variadic parameters", (StringRef))
31403126
ERROR(attr_not_on_subscript_parameters,none,
31413127
"'%0' must not be used on subscript parameters", (StringRef))
3128+
ERROR(attr_not_on_stored_properties,none,
3129+
"'%0' must not be used on stored properties", (DeclAttribute))
3130+
3131+
WARNING(attr_has_no_effect_on_decl_with_access_level,none,
3132+
"'%0' does not have any effect on "
3133+
"%select{private|fileprivate|internal|%error|%error}1 declarations",
3134+
(DeclAttribute, AccessLevel))
3135+
ERROR(attr_not_on_decl_with_invalid_access_level,none,
3136+
"'%0' may not be used on "
3137+
"%select{private|fileprivate|internal|%error|%error}1 declarations",
3138+
(DeclAttribute, AccessLevel))
3139+
3140+
ERROR(attr_has_no_effect_decl_not_available_before,none,
3141+
"'%0' has no effect because %1 is not available before %2 %3",
3142+
(DeclAttribute, DeclName, StringRef, llvm::VersionTuple))
31423143

31433144
ERROR(attr_ambiguous_reference_to_decl,none,
31443145
"ambiguous reference to %0 in '@%1' attribute", (DeclNameRef, StringRef))
31453146

3147+
ERROR(attr_contains_multiple_versions_for_platform,none,
3148+
"'%0' contains multiple versions for %1", (DeclAttribute, StringRef))
3149+
31463150
ERROR(override_final,none,
31473151
"%0 overrides a 'final' %1", (DescriptiveDeclKind, DescriptiveDeclKind))
31483152

@@ -3157,6 +3161,10 @@ ERROR(final_not_allowed_here,none,
31573161
"'final' may only be applied to classes, properties, methods, and "
31583162
"subscripts", ())
31593163

3164+
ERROR(attr_incompatible_with_non_final,none,
3165+
"'%0' cannot be applied to a non-final %1",
3166+
(DeclAttribute, DescriptiveDeclKind))
3167+
31603168
ERROR(final_not_on_accessors,none,
31613169
"'final' cannot be applied to accessors, it must be put on the "
31623170
"%select{var|let|subscript}0", (unsigned))
@@ -5615,6 +5623,14 @@ ERROR(availability_macro_in_inlinable, none,
56155623
"availability macro cannot be used in inlinable %0",
56165624
(DescriptiveDeclKind))
56175625

5626+
ERROR(attr_requires_decl_availability_for_platform,none,
5627+
"'%0' requires that %1 have explicit availability for %2",
5628+
(DeclAttribute, DeclName, StringRef))
5629+
5630+
ERROR(attr_requires_availability_for_platform,none,
5631+
"'%0' requires explicit availability for %1",
5632+
(DeclAttribute, StringRef))
5633+
56185634
// This doesn't display as an availability diagnostic, but it's
56195635
// implemented there and fires when these subscripts are marked
56205636
// unavailable, so it seems appropriate to put it here.
@@ -6164,6 +6180,10 @@ ERROR(differentiable_programming_attr_used_without_required_module, none,
61646180
"'@%0' attribute used without importing module %1",
61656181
(StringRef, Identifier))
61666182

6183+
//------------------------------------------------------------------------------
6184+
// MARK: OSLog
6185+
//------------------------------------------------------------------------------
6186+
61676187
ERROR(oslog_arg_must_be_bool_literal, none,
61686188
"argument must be a bool literal", ())
61696189
ERROR(oslog_arg_must_be_integer_literal, none,
@@ -6271,5 +6291,13 @@ ERROR(cannot_convert_default_value_type_to_argument_type, none,
62716291
"cannot convert default value of type %0 to expected argument type %1 for parameter #%2",
62726292
(Type, Type, unsigned))
62736293

6294+
//------------------------------------------------------------------------------
6295+
// MARK: Back deployment
6296+
//------------------------------------------------------------------------------
6297+
6298+
ERROR(attr_incompatible_with_back_deploy,none,
6299+
"'%0' cannot be applied to a back deployed %1",
6300+
(DeclAttribute, DescriptiveDeclKind))
6301+
62746302
#define UNDEFINE_DIAGNOSTIC_MACROS
62756303
#include "DefineDiagnosticMacros.h"

lib/AST/Decl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,18 @@ Decl::getIntroducedOSVersion(PlatformKind Kind) const {
377377
return None;
378378
}
379379

380+
Optional<llvm::VersionTuple>
381+
Decl::getBackDeployBeforeOSVersion(PlatformKind Kind) const {
382+
for (auto *attr : getAttrs()) {
383+
if (auto *backDeployAttr = dyn_cast<BackDeployAttr>(attr)) {
384+
if (backDeployAttr->Platform == Kind && backDeployAttr->Version) {
385+
return backDeployAttr->Version;
386+
}
387+
}
388+
}
389+
return None;
390+
}
391+
380392
llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &OS,
381393
StaticSpellingKind SSK) {
382394
switch (SSK) {

lib/AST/DeclContext.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,8 @@ swift::FragileFunctionKindRequest::evaluate(Evaluator &evaluator,
424424
/*allowUsableFromInline=*/true};
425425
}
426426

427-
// If a property or subscript is @inlinable or @_alwaysEmitIntoClient,
428-
// the accessors are @inlinable or @_alwaysEmitIntoClient also.
427+
// Property and subscript accessors inherit @_alwaysEmitIntoClient,
428+
// @_backDeploy, and @inlinable from their storage declarations.
429429
if (auto accessor = dyn_cast<AccessorDecl>(AFD)) {
430430
auto *storage = accessor->getStorage();
431431
if (storage->getAttrs().getAttribute<InlinableAttr>()) {
@@ -436,6 +436,10 @@ swift::FragileFunctionKindRequest::evaluate(Evaluator &evaluator,
436436
return {FragileFunctionKind::AlwaysEmitIntoClient,
437437
/*allowUsableFromInline=*/true};
438438
}
439+
if (storage->getAttrs().hasAttribute<BackDeployAttr>()) {
440+
return {FragileFunctionKind::BackDeploy,
441+
/*allowUsableFromInline=*/true};
442+
}
439443
}
440444
}
441445
}

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,10 +1030,8 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
10301030
}
10311031

10321032
void processClassMethod(DeclRefExpr *e, AbstractFunctionDecl *afd) {
1033-
// FIXME(backDeploy): Investigate support for back deployed class method
1034-
// calls
10351033
assert(!afd->isBackDeployed() &&
1036-
"back deployed method calls are unsupported");
1034+
"cannot back deploy dynamically dispatched methods");
10371035

10381036
ArgumentSource selfArgSource(selfApply->getBase());
10391037
setSelfParam(std::move(selfArgSource));

lib/SILGen/SILGenBackDeploy.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ static void emitBackDeployIfAvailableCondition(SILGenFunction &SGF,
5353
SILBasicBlock *availableBB,
5454
SILBasicBlock *unavailableBB) {
5555
PlatformKind platform = targetPlatform(SGF.SGM.getASTContext().LangOpts);
56-
auto introduced = AFD->getIntroducedOSVersion(platform);
56+
auto version = AFD->getBackDeployBeforeOSVersion(platform);
5757
VersionRange OSVersion = VersionRange::empty();
58-
if (introduced.hasValue()) {
59-
OSVersion = VersionRange::allGTE(*introduced);
58+
if (version.hasValue()) {
59+
OSVersion = VersionRange::allGTE(*version);
6060
}
6161

6262
SILValue booleanTestValue;

0 commit comments

Comments
 (0)