Skip to content

Commit 0543c28

Browse files
authored
Merge pull request #63986 from beccadax/dont-print-as-objc
Exclude @objcImpl member impls from PrintAsObjC
2 parents e770bbe + 1629521 commit 0543c28

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2783,14 +2783,34 @@ static bool hasExposeAttr(const ValueDecl *VD, bool isExtension = false) {
27832783
return false;
27842784
}
27852785

2786+
/// Skip \c \@objcImplementation \c extension member implementations and
2787+
/// overrides. They are already declared in handwritten headers, and they may
2788+
/// have attributes that aren't allowed in a category.
2789+
///
2790+
/// \return true if \p VD should \em not be included in the header.
2791+
static bool excludeForObjCImplementation(const ValueDecl *VD) {
2792+
// Exclude member implementations; they are declared elsewhere.
2793+
if (VD->isObjCMemberImplementation())
2794+
return true;
2795+
// Exclude overrides in an @_objcImplementation extension; the decl they're
2796+
// overriding is declared elsewhere.
2797+
if (VD->isImplicit() && VD->getOverriddenDecl()) {
2798+
auto ED = dyn_cast<ExtensionDecl>(VD->getDeclContext());
2799+
if (ED && ED->isObjCImplementation())
2800+
return true;
2801+
}
2802+
return false;
2803+
}
2804+
27862805
bool DeclAndTypePrinter::shouldInclude(const ValueDecl *VD) {
27872806
return !VD->isInvalid() && (!requiresExposedAttribute || hasExposeAttr(VD)) &&
27882807
(outputLang == OutputLanguageMode::Cxx
27892808
? cxx_translation::isVisibleToCxx(VD, minRequiredAccess) &&
27902809
cxx_translation::isExposableToCxx(VD)
27912810
: isVisibleToObjC(VD, minRequiredAccess)) &&
27922811
!VD->getAttrs().hasAttribute<ImplementationOnlyAttr>() &&
2793-
!isAsyncAlternativeOfOtherDecl(VD);
2812+
!isAsyncAlternativeOfOtherDecl(VD) &&
2813+
!excludeForObjCImplementation(VD);
27942814
}
27952815

27962816
void DeclAndTypePrinter::print(const Decl *D) {

test/PrintAsObjC/Inputs/custom-modules/module.map

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,8 @@ module EmitClangHeaderNonmodularIncludesStressTest {
5858
header "header_subdirectory/header-symlink.h"
5959
export *
6060
}
61+
62+
module objc_implementation {
63+
header "objc_implementation/objc_implementation.h"
64+
export *
65+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#import <Foundation.h>
2+
3+
@interface ObjCClass : NSObject
4+
5+
- (nullable id)swiftMethod;
6+
7+
@end
8+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Please keep this file in alphabetical order!
2+
3+
// REQUIRES: objc_interop
4+
5+
// RUN: %empty-directory(%t)
6+
7+
// FIXME: BEGIN -enable-source-import hackaround
8+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -disable-objc-attr-requires-foundation-module
9+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
10+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
11+
// FIXME: END -enable-source-import hackaround
12+
13+
14+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -I %S/Inputs/custom-modules -import-underlying-module -o %t %s -disable-objc-attr-requires-foundation-module
15+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -parse-as-library %t/objc_implementation.swiftmodule -typecheck -I %S/Inputs/custom-modules -emit-objc-header-path %t/objc_implementation-Swift.h -import-underlying-module -disable-objc-attr-requires-foundation-module
16+
// RUN: %FileCheck %s --input-file %t/objc_implementation-Swift.h
17+
// RUN: %FileCheck --check-prefix=NEGATIVE %s --input-file %t/objc_implementation-Swift.h
18+
// RUN: %check-in-clang -I %S/Inputs/custom-modules/ %t/objc_implementation-Swift.h
19+
// RUN: %check-in-clang -I %S/Inputs/custom-modules/ -fno-modules -Qunused-arguments %t/objc_implementation-Swift.h
20+
21+
import Foundation
22+
23+
extension ObjCClass {
24+
// CHECK: - (id _Nullable)pureSwiftMethod SWIFT_WARN_UNUSED_RESULT;
25+
@objc public func pureSwiftMethod() -> Any? { nil }
26+
}
27+
28+
@_objcImplementation extension ObjCClass {
29+
// NEGATIVE-NOT: )init{{ }}
30+
// Implicit `override init()` to override superclass
31+
32+
// NEGATIVE-NOT: )swiftMethod{{ }}
33+
@objc func swiftMethod() -> Any? { nil }
34+
35+
// NEGATIVE-NOT: )privateMethod{{ }}
36+
@objc private func privateMethod() -> Any? { nil }
37+
}

0 commit comments

Comments
 (0)