Skip to content

Commit 0b78426

Browse files
authored
[CodeGen][ObjC] Include all referenced protocols in protocol list (#148827)
When constructing the protocol list in the class metadata generation (`GenerateClass`), only the protocols from the base class are added but not protocols declared in class extensions. This is fixed by using `all_referenced_protocol_{begin, end}` instead of `protocol_{begin, end}`, matching the behaviour on Apple platforms. A unit test is included to check if all protocol metadata was emitted and that no duplication occurs in the protocol list. Fixes gnustep/libobjc2#339 CC: @davidchisnall
1 parent acffe83 commit 0b78426

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

clang/lib/CodeGen/CGObjCGNU.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,8 +1942,9 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
19421942
// struct objc_class *sibling_class
19431943
classFields.addNullPointer(PtrTy);
19441944
// struct objc_protocol_list *protocols;
1945-
auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->protocol_begin(),
1946-
classDecl->protocol_end());
1945+
auto RuntimeProtocols =
1946+
GetRuntimeProtocolList(classDecl->all_referenced_protocol_begin(),
1947+
classDecl->all_referenced_protocol_end());
19471948
SmallVector<llvm::Constant *, 16> Protocols;
19481949
for (const auto *I : RuntimeProtocols)
19491950
Protocols.push_back(GenerateProtocolRef(I));
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -fobjc-runtime=gnustep-2.2 -emit-llvm -o - %s | FileCheck %s
2+
3+
@protocol BaseProtocol
4+
@end
5+
6+
@protocol ExtendedProtocol
7+
@end
8+
9+
@interface TestClass <BaseProtocol>
10+
11+
-(void) Meth;
12+
@end
13+
14+
@interface TestClass () <BaseProtocol, ExtendedProtocol>
15+
@end
16+
17+
@implementation TestClass
18+
@end
19+
20+
// Check that we emit metadata for both protocols
21+
// CHECK: @._OBJC_PROTOCOL_ExtendedProtocol = global
22+
// CHECK: @._OBJC_PROTOCOL_BaseProtocol = global
23+
24+
// Check that we deduplicate the protocol list
25+
// CHECK: @.objc_protocol_list{{\.[0-9]*}} = internal global { ptr, i64, [2 x ptr] }

0 commit comments

Comments
 (0)