Skip to content

Commit 576a4ba

Browse files
authored
Merge pull request #72596 from beccadax/objcimpl-real-name
Add @implementation and feature flags for objcImpl
2 parents 4a0f380 + 05e93da commit 576a4ba

26 files changed

+226
-61
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,11 @@ of a header as non-`Sendable` so that you can make spot exceptions with
779779

780780
## `@_objcImplementation(CategoryName)`
781781

782+
A pre-stable form of `@implementation`. The main difference between them is that
783+
many things that are errors with `@implementation` are warnings with
784+
`@_objcImplementation`, which permitted workarounds for compiler bugs and
785+
changes in compiler behavior.
786+
782787
Declares an extension that defines an implementation for the Objective-C
783788
category `CategoryName` on the class in question, or for the main `@interface`
784789
if the argument list is omitted.
@@ -841,12 +846,6 @@ Notes:
841846

842847
* We don't currently plan to support ObjC generics.
843848

844-
* Eventually, we want the main `@_objcImplementation` extension to be able to
845-
declare stored properties that aren't in the interface. We also want
846-
`final` stored properties to be allowed to be resilent Swift types, but
847-
it's not clear how to achieve that without boxing them in `__SwiftValue`
848-
(which we might do as a stopgap).
849-
850849
* We should think about ObjC "direct" members, but that would probably
851850
require a way to spell this in Swift.
852851

include/swift/AST/ASTBridging.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,10 @@ BridgedObjCAttr BridgedObjCAttr_createParsedSelector(
625625
BridgedArrayRef cNameLocs, BridgedArrayRef cNames,
626626
BridgedSourceLoc cRParenLoc);
627627

628-
SWIFT_NAME("BridgedObjCImplementationAttr.createParsed(_:atLoc:range:name:)")
628+
SWIFT_NAME("BridgedObjCImplementationAttr.createParsed(_:atLoc:range:name:isEarlyAdopter:)")
629629
BridgedObjCImplementationAttr BridgedObjCImplementationAttr_createParsed(
630630
BridgedASTContext cContext, BridgedSourceLoc cAtLoc,
631-
BridgedSourceRange cRange, BridgedIdentifier cName);
631+
BridgedSourceRange cRange, BridgedIdentifier cName, bool isEarlyAdopter);
632632

633633
SWIFT_NAME("BridgedObjCRuntimeNameAttr.createParsed(_:atLoc:range:name:)")
634634
BridgedObjCRuntimeNameAttr BridgedObjCRuntimeNameAttr_createParsed(

include/swift/AST/Attr.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,9 @@ class DeclAttribute : public AttributeBase {
184184
isUnchecked : 1
185185
);
186186

187-
SWIFT_INLINE_BITFIELD(ObjCImplementationAttr, DeclAttribute, 1,
188-
isCategoryNameInvalid : 1
187+
SWIFT_INLINE_BITFIELD(ObjCImplementationAttr, DeclAttribute, 2,
188+
isCategoryNameInvalid : 1,
189+
isEarlyAdopter : 1
189190
);
190191

191192
SWIFT_INLINE_BITFIELD(NonisolatedAttr, DeclAttribute, 1,
@@ -2424,11 +2425,19 @@ class ObjCImplementationAttr final : public DeclAttribute {
24242425
Identifier CategoryName;
24252426

24262427
ObjCImplementationAttr(Identifier CategoryName, SourceLoc AtLoc,
2427-
SourceRange Range, bool Implicit = false,
2428+
SourceRange Range, bool isEarlyAdopter = false,
2429+
bool Implicit = false,
24282430
bool isCategoryNameInvalid = false)
24292431
: DeclAttribute(DeclAttrKind::ObjCImplementation, AtLoc, Range, Implicit),
24302432
CategoryName(CategoryName) {
24312433
Bits.ObjCImplementationAttr.isCategoryNameInvalid = isCategoryNameInvalid;
2434+
Bits.ObjCImplementationAttr.isEarlyAdopter = isEarlyAdopter;
2435+
}
2436+
2437+
/// Early adopters use the \c \@_objcImplementation spelling. For backwards
2438+
/// compatibility, issues with them are diagnosed as warnings, not errors.
2439+
bool isEarlyAdopter() const {
2440+
return Bits.ObjCImplementationAttr.isEarlyAdopter;
24322441
}
24332442

24342443
bool isCategoryNameInvalid() const {

include/swift/AST/DeclAttr.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,10 @@ SIMPLE_DECL_ATTR(_staticInitializeObjCMetadata, StaticInitializeObjCMetadata,
188188
DECL_ATTR(_restatedObjCConformance, RestatedObjCConformance,
189189
OnProtocol | UserInaccessible | LongAttribute | RejectByParser | NotSerialized | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
190190
70)
191-
DECL_ATTR(_objcImplementation, ObjCImplementation,
191+
DECL_ATTR(implementation, ObjCImplementation,
192192
OnExtension | OnAbstractFunction | UserInaccessible | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
193193
72)
194+
DECL_ATTR_ALIAS(_objcImplementation, ObjCImplementation)
194195
DECL_ATTR(_optimize, Optimize,
195196
OnAbstractFunction | OnSubscript | OnVar | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
196197
73)

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,9 @@ ERROR(swift_native_objc_runtime_base_not_on_root_class,none,
17391739
"@_swift_native_objc_runtime_base_not_on_root_class can only be applied "
17401740
"to root classes", ())
17411741

1742+
WARNING(objc_implementation_early_spelling_deprecated,none,
1743+
"'@_objcImplementation' is deprecated; use '@implementation' instead",
1744+
())
17421745
ERROR(attr_objc_implementation_must_be_unconditional,none,
17431746
"only unconditional extensions can implement an Objective-C '@interface'",
17441747
())
@@ -1917,8 +1920,7 @@ NOTE(objc_implementation_one_matched_requirement,none,
19171920
(ValueDecl *, ObjCSelector, bool, StringRef))
19181921

19191922
WARNING(wrap_objc_implementation_will_become_error,none,
1920-
"%0; this will become an error before '@_objcImplementation' is "
1921-
"stabilized",
1923+
"%0; this will become an error after adopting '@implementation'",
19221924
(DiagnosticInfo *))
19231925

19241926
ERROR(cdecl_not_at_top_level,none,

include/swift/Basic/Features.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,12 @@ EXPERIMENTAL_FEATURE(IsolatedAny2, true)
367367
// Enable usability improvements for global-actor-isolated types.
368368
EXPERIMENTAL_FEATURE(GlobalActorIsolatedTypesUsability, false)
369369

370+
// Enable @implementation on extensions of ObjC classes.
371+
EXPERIMENTAL_FEATURE(ObjCImplementation, true)
372+
373+
// Enable @implementation on @_cdecl functions.
374+
EXPERIMENTAL_FEATURE(CImplementation, true)
375+
370376
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
371377
#undef EXPERIMENTAL_FEATURE
372378
#undef UPCOMING_FEATURE

lib/AST/ASTBridging.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,9 +662,10 @@ BridgedObjCAttr BridgedObjCAttr_createParsedSelector(
662662

663663
BridgedObjCImplementationAttr BridgedObjCImplementationAttr_createParsed(
664664
BridgedASTContext cContext, BridgedSourceLoc cAtLoc,
665-
BridgedSourceRange cRange, BridgedIdentifier cName) {
665+
BridgedSourceRange cRange, BridgedIdentifier cName, bool isEarlyAdopter) {
666666
return new (cContext.unbridged()) ObjCImplementationAttr(
667-
cName.unbridged(), cAtLoc.unbridged(), cRange.unbridged());
667+
cName.unbridged(), cAtLoc.unbridged(), cRange.unbridged(),
668+
isEarlyAdopter);
668669
}
669670

670671
BridgedObjCRuntimeNameAttr BridgedObjCRuntimeNameAttr_createParsed(

lib/AST/ASTDumper.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,16 @@ namespace {
10841084

10851085
printFlag(D->isImplicit(), "implicit", DeclModifierColor);
10861086
printFlag(D->isHoisted(), "hoisted", DeclModifierColor);
1087+
1088+
if (auto implAttr = D->getAttrs().getAttribute<ObjCImplementationAttr>()) {
1089+
StringRef label =
1090+
implAttr->isEarlyAdopter() ? "objc_impl" : "clang_impl";
1091+
if (implAttr->CategoryName.empty())
1092+
printFlag(label);
1093+
else
1094+
printFieldQuoted(implAttr->CategoryName.str(), label);
1095+
}
1096+
10871097
printSourceRange(D->getSourceRange(), &D->getASTContext());
10881098
printFlag(D->TrailingSemiLoc.isValid(), "trailing_semi",
10891099
DeclModifierColor);

lib/AST/Attr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1820,7 +1820,9 @@ StringRef DeclAttribute::getAttrName() const {
18201820
case DeclAttrKind::ObjCRuntimeName:
18211821
return "objc";
18221822
case DeclAttrKind::ObjCImplementation:
1823-
return "_objcImplementation";
1823+
if (cast<ObjCImplementationAttr>(this)->isEarlyAdopter())
1824+
return "_objcImplementation";
1825+
return "implementation";
18241826
case DeclAttrKind::MainType:
18251827
return "main";
18261828
case DeclAttrKind::DynamicReplacement:

lib/AST/FeatureSet.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,9 @@ static bool usesFeatureGlobalActorIsolatedTypesUsability(Decl *decl) {
687687
return false;
688688
}
689689

690+
UNINTERESTING_FEATURE(ObjCImplementation)
691+
UNINTERESTING_FEATURE(CImplementation)
692+
690693
// ----------------------------------------------------------------------------
691694
// MARK: - FeatureSet
692695
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)