Skip to content

Commit 231de1a

Browse files
committed
Add ObjCReason for @objcImpl
Besides improving diagnostics, this also allows us to track whether there were any @objc failures using the invalid bit on the @_objcImplementation attribute.
1 parent 76f25e5 commit 231de1a

File tree

5 files changed

+16
-7
lines changed

5 files changed

+16
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6100,7 +6100,7 @@ ERROR(objc_extension_not_class,none,
61006100
"'@objc' can only be applied to an extension of a class", ())
61016101

61026102
// If you change this, also change enum ObjCReason
6103-
#define OBJC_ATTR_SELECT "select{marked @_cdecl|marked dynamic|marked @objc|marked @objcMembers|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)|marked @objc by an access note}"
6103+
#define OBJC_ATTR_SELECT "select{marked @_cdecl|marked dynamic|marked @objc|marked @objcMembers|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)|in an @_objcImplementation extension of a class (without final or @nonobjc)|marked @objc by an access note}"
61046104

61056105
WARNING(attribute_meaningless_when_nonobjc,none,
61066106
"'@%0' attribute is meaningless on a property that cannot be "

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1818,7 +1818,7 @@ Type ExtensionDecl::getExtendedType() const {
18181818
}
18191819

18201820
bool ExtensionDecl::isObjCImplementation() const {
1821-
return getAttrs().hasAttribute<ObjCImplementationAttr>();
1821+
return getAttrs().hasAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true);
18221822
}
18231823

18241824
llvm::Optional<Identifier>

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ swift::behaviorLimitForObjCReason(ObjCReason reason, ASTContext &ctx) {
5151
case ObjCReason::WitnessToObjC:
5252
case ObjCReason::ImplicitlyObjC:
5353
case ObjCReason::MemberOfObjCExtension:
54+
case ObjCReason::MemberOfObjCImplementationExtension:
5455
return DiagnosticBehavior::Unspecified;
5556

5657
case ObjCReason::ExplicitlyIBInspectable:
@@ -88,6 +89,7 @@ unsigned swift::getObjCDiagnosticAttrKind(ObjCReason reason) {
8889
case ObjCReason::ExplicitlyIBInspectable:
8990
case ObjCReason::ExplicitlyGKInspectable:
9091
case ObjCReason::MemberOfObjCExtension:
92+
case ObjCReason::MemberOfObjCImplementationExtension:
9193
case ObjCReason::ExplicitlyObjCByAccessNote:
9294
return static_cast<unsigned>(reason);
9395

@@ -137,6 +139,7 @@ void ObjCReason::describe(const Decl *D) const {
137139
case ObjCReason::MemberOfObjCExtension:
138140
case ObjCReason::MemberOfObjCMembersClass:
139141
case ObjCReason::MemberOfObjCSubclass:
142+
case ObjCReason::MemberOfObjCImplementationExtension:
140143
case ObjCReason::ElementOfObjCEnum:
141144
case ObjCReason::Accessor:
142145
// No additional note required.
@@ -1463,9 +1466,12 @@ static llvm::Optional<ObjCReason> shouldMarkAsObjC(const ValueDecl *VD,
14631466
}
14641467

14651468
// A member implementation of an @objcImplementation extension is @objc.
1466-
if (VD->isObjCMemberImplementation())
1467-
// FIXME: New ObjCReason::Kind?
1468-
return ObjCReason(ObjCReason::ImplicitlyObjC);
1469+
if (VD->isObjCMemberImplementation()) {
1470+
auto ext = VD->getDeclContext()->getAsDecl();
1471+
auto attr = ext->getAttrs()
1472+
.getAttribute<ObjCImplementationAttr>(/*AllowInvalid=*/true);
1473+
return ObjCReason(ObjCReason::MemberOfObjCImplementationExtension, attr);
1474+
}
14691475

14701476
// A @nonobjc is not @objc, even if it is an override of an @objc, so check
14711477
// for @nonobjc first.

lib/Sema/TypeCheckObjC.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class ObjCReason {
7171
ExplicitlyGKInspectable,
7272
/// Is it a member of an @objc extension of a class.
7373
MemberOfObjCExtension,
74+
/// Is it a member of an \@\_objcImplementation extension.
75+
MemberOfObjCImplementationExtension,
7476
/// Has an explicit '@objc' attribute added by an access note, rather than
7577
/// written in source code.
7678
ExplicitlyObjCByAccessNote,
@@ -108,6 +110,7 @@ class ObjCReason {
108110
case ExplicitlyNSManaged:
109111
case ExplicitlyIBInspectable:
110112
case ExplicitlyGKInspectable:
113+
case MemberOfObjCImplementationExtension:
111114
case ExplicitlyObjCByAccessNote:
112115
return true;
113116

test/decl/ext/objc_implementation.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,8 @@ protocol EmptySwiftProto {}
412412
func nullableResult() -> Any { fatalError() } // expected-warning {{instance method 'nullableResult()' of type '() -> Any' does not match type '() -> Any?' declared by the header}}
413413
func nullableArgument(_: Any) {} // expected-warning {{instance method 'nullableArgument' of type '(Any) -> ()' does not match type '(Any?) -> Void' declared by the header}}
414414

415-
func nonPointerResult() -> CInt! { fatalError() } // expected-error{{method cannot be implicitly @objc because its result type cannot be represented in Objective-C}}
416-
func nonPointerArgument(_: CInt!) {} // expected-error {{method cannot be implicitly @objc because the type of the parameter cannot be represented in Objective-C}}
415+
func nonPointerResult() -> CInt! { fatalError() } // expected-error{{method cannot be in an @_objcImplementation extension of a class (without final or @nonobjc) because its result type cannot be represented in Objective-C}}
416+
func nonPointerArgument(_: CInt!) {} // expected-error {{method cannot be in an @_objcImplementation extension of a class (without final or @nonobjc) because the type of the parameter cannot be represented in Objective-C}}
417417
}
418418

419419
@_objcImplementation extension ObjCImplSubclass {

0 commit comments

Comments
 (0)