Skip to content

Commit 85019e8

Browse files
authored
[ClangImporter] Structs lexically in an ObjC class are still top-level. (#10874)
Not every declaration that's syntactically in an Objective-C container is a member of that container. Double-check the decl context before adding it. This is technically a breaking change in non-asserts builds, because the struct really could be found via member lookup. But that should be considered a bug, and I /suspect/ no one is relying on it. rdar://problem/32451417
1 parent 7a92acb commit 85019e8

File tree

4 files changed

+76
-1
lines changed

4 files changed

+76
-1
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8002,8 +8002,10 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
80028002
llvm::SmallPtrSet<Decl *, 4> knownAlternateMembers;
80038003
for (const clang::Decl *m : objcContainer->decls()) {
80048004
auto nd = dyn_cast<clang::NamedDecl>(m);
8005-
if (!nd || nd != nd->getCanonicalDecl())
8005+
if (!nd || nd != nd->getCanonicalDecl() ||
8006+
nd->getDeclContext() != objcContainer) {
80068007
continue;
8008+
}
80078009

80088010
forEachDistinctName(nd,
80098011
[&](ImportedName name, ImportNameVersion nameVersion) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@interface Base
2+
@end
3+
4+
struct AlreadyDeclaredStruct {
5+
int value;
6+
};
7+
8+
#if defined(CLASS)
9+
@interface Wrapper : Base
10+
#elif defined(CATEGORY)
11+
@interface Wrapper : Base
12+
@end
13+
@interface Wrapper (Category)
14+
#elif defined(PROTOCOL)
15+
@protocol Wrapper
16+
#else
17+
# error "Must pick a variant"
18+
#endif
19+
20+
extern void nestedFunc(void);
21+
22+
@property struct ForwardDeclaredStruct forward;
23+
@property struct AlreadyDeclaredStruct backward;
24+
25+
struct NestedDeclaredStruct {
26+
int value;
27+
};
28+
typedef int NestedTypedef;
29+
extern const int nestedGlobal;
30+
31+
@end
32+
33+
struct ForwardDeclaredStruct {
34+
int value;
35+
};

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ module CFAndObjC {
1212
export *
1313
}
1414

15+
module CInsideObjC {
16+
header "CInsideObjC.h"
17+
export *
18+
}
19+
1520
module ClangModuleUser {
1621
header "ClangModuleUser.h"
1722
export *
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print CInsideObjC -I %S/Inputs/custom-modules -source-filename %s -Xcc -DCLASS | %FileCheck %s
2+
// RUN: %target-swift-ide-test -print-module -module-to-print CInsideObjC -I %S/Inputs/custom-modules -source-filename %s -Xcc -DCATEGORY | %FileCheck %s
3+
// RUN: %target-swift-ide-test -print-module -module-to-print CInsideObjC -I %S/Inputs/custom-modules -source-filename %s -Xcc -DPROTOCOL | %FileCheck %s
4+
5+
// RUN: %target-swift-frontend -typecheck %s -I %S/Inputs/custom-modules -verify -Xcc -DCLASS
6+
// RUN: %target-swift-frontend -typecheck %s -I %S/Inputs/custom-modules -verify -Xcc -DCATEGORY
7+
// RUN: %target-swift-frontend -typecheck %s -I %S/Inputs/custom-modules -verify -Xcc -DPROTOCOL
8+
9+
// REQUIRES: objc_interop
10+
11+
// CHECK-LABEL: struct AlreadyDeclaredStruct {
12+
13+
// CHECK-LABEL: {{class Wrapper : Base {|extension Wrapper {|protocol Wrapper {}}
14+
// CHECK-NOT: struct
15+
// CHECK: var forward: ForwardDeclaredStruct
16+
// CHECK-NOT: struct
17+
// CHECK: var backward: AlreadyDeclaredStruct
18+
// CHECK-NOT: struct
19+
// CHECK: {{^}$}}
20+
21+
// CHECK-LABEL: func nestedFunc()
22+
// CHECK-LABEL: struct NestedDeclaredStruct {
23+
// CHECK-LABEL: typealias NestedTypedef = Int32
24+
// CHECK-LABEL: let nestedGlobal: Int32
25+
26+
// CHECK-LABEL: struct ForwardDeclaredStruct {
27+
28+
import CInsideObjC
29+
30+
func testTypeLookup(_: AlreadyDeclaredStruct) {}
31+
func testTypeLookup(_: NestedDeclaredStruct) {}
32+
func testTypeLookup(_: ForwardDeclaredStruct) {}
33+
func testTypeLookup(_: NestedTypedef) {}

0 commit comments

Comments
 (0)