3 ; Here we test that if we defined
a protocol MyTestProtocol
and also
a category MyTestProtocol
4 ; then when merging the category into the base class
(and deleting the category
), we don
't
5 ; delete the 'MyTestProtocol
' name
7 ; RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o erase-objc-name.o %s
8 ; RUN: %lld -arch arm64 -dylib -o erase-objc-name.dylib erase-objc-name.o -objc_category_merging
9 ; RUN: llvm-objdump --objc-meta-data --macho erase-objc-name.dylib | FileCheck %s --check-prefixes=MERGE_CATS
11 ; === Check merge categories enabled ===
12 ; Check that the original categories are not there
13 ; MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01
14 ; MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
16 ; Check that we get the expected output - most importantly that the protocol is named `MyTestProtocol`
17 ; MERGE_CATS: Contents of (__DATA_CONST,__objc_classlist) section
18 ; MERGE_CATS-NEXT: _OBJC_CLASS_$_MyBaseClass
19 ; MERGE_CATS-NEXT: isa {{.*}} _OBJC_METACLASS_$_MyBaseClass
20 ; MERGE_CATS-NEXT: superclass {{.*}}
21 ; MERGE_CATS-NEXT: cache {{.*}}
22 ; MERGE_CATS-NEXT: vtable {{.*}}
23 ; MERGE_CATS-NEXT: data {{.*}} (struct class_ro_t *)
24 ; MERGE_CATS-NEXT: flags {{.*}} RO_ROOT
25 ; MERGE_CATS-NEXT: instanceStart 0
26 ; MERGE_CATS-NEXT: instanceSize 0
27 ; MERGE_CATS-NEXT: reserved {{.*}}
28 ; MERGE_CATS-NEXT: ivarLayout {{.*}}
29 ; MERGE_CATS-NEXT: name {{.*}} MyBaseClass
30 ; MERGE_CATS-NEXT: baseMethods {{.*}} (struct method_list_t *)
31 ; MERGE_CATS-NEXT: entsize 24
32 ; MERGE_CATS-NEXT: count 2
33 ; MERGE_CATS-NEXT: name {{.*}} getValue
34 ; MERGE_CATS-NEXT: types {{.*}} i16@0:8
35 ; MERGE_CATS-NEXT: imp -[MyBaseClass(MyTestProtocol) getValue]
36 ; MERGE_CATS-NEXT: name {{.*}} baseInstanceMethod
37 ; MERGE_CATS-NEXT: types {{.*}} v16@0:8
38 ; MERGE_CATS-NEXT: imp -[MyBaseClass baseInstanceMethod]
39 ; MERGE_CATS-NEXT: baseProtocols {{.*}}
40 ; MERGE_CATS-NEXT: count 1
41 ; MERGE_CATS-NEXT: list[0] {{.*}} (struct protocol_t *)
42 ; MERGE_CATS-NEXT: isa {{.*}}
43 ; MERGE_CATS-NEXT: name {{.*}} MyTestProtocol
44 ; MERGE_CATS-NEXT: protocols {{.*}}
45 ; MERGE_CATS-NEXT: instanceMethods {{.*}} (struct method_list_t *)
46 ; MERGE_CATS-NEXT: entsize 24
47 ; MERGE_CATS-NEXT: count 1
48 ; MERGE_CATS-NEXT: name {{.*}} getValue
49 ; MERGE_CATS-NEXT: types {{.*}} i16@0:8
50 ; MERGE_CATS-NEXT: imp {{.*}}
51 ; MERGE_CATS-NEXT: classMethods {{.*}} (struct method_list_t *)
52 ; MERGE_CATS-NEXT: optionalInstanceMethods {{.*}}
53 ; MERGE_CATS-NEXT: optionalClassMethods {{.*}}
54 ; MERGE_CATS-NEXT: instanceProperties {{.*}}
55 ; MERGE_CATS-NEXT: ivars {{.*}}
56 ; MERGE_CATS-NEXT: weakIvarLayout {{.*}}
57 ; MERGE_CATS-NEXT: baseProperties {{.*}}
58 ; MERGE_CATS-NEXT: Meta Class
59 ; MERGE_CATS-NEXT: isa {{.*}} _OBJC_METACLASS_$_MyBaseClass
60 ; MERGE_CATS-NEXT: superclass {{.*}} _OBJC_CLASS_$_MyBaseClass
61 ; MERGE_CATS-NEXT: cache {{.*}}
62 ; MERGE_CATS-NEXT: vtable {{.*}}
63 ; MERGE_CATS-NEXT: data {{.*}} (struct class_ro_t *)
64 ; MERGE_CATS-NEXT: flags {{.*}} RO_META RO_ROOT
65 ; MERGE_CATS-NEXT: instanceStart 40
66 ; MERGE_CATS-NEXT: instanceSize 40
67 ; MERGE_CATS-NEXT: reserved {{.*}}
68 ; MERGE_CATS-NEXT: ivarLayout {{.*}}
69 ; MERGE_CATS-NEXT: name {{.*}} MyBaseClass
70 ; MERGE_CATS-NEXT: baseMethods {{.*}} (struct method_list_t *)
71 ; MERGE_CATS-NEXT: baseProtocols {{.*}}
72 ; MERGE_CATS-NEXT: count 1
73 ; MERGE_CATS-NEXT: list[0] {{.*}} (struct protocol_t *)
74 ; MERGE_CATS-NEXT: isa {{.*}}
75 ; MERGE_CATS-NEXT: name {{.*}} MyTestProtocol
76 ; MERGE_CATS-NEXT: protocols {{.*}}
77 ; MERGE_CATS-NEXT: instanceMethods {{.*}} (struct method_list_t *)
78 ; MERGE_CATS-NEXT: entsize 24
79 ; MERGE_CATS-NEXT: count 1
80 ; MERGE_CATS-NEXT: name {{.*}} getValue
81 ; MERGE_CATS-NEXT: types {{.*}} i16@0:8
82 ; MERGE_CATS-NEXT: imp {{.*}}
83 ; MERGE_CATS-NEXT: classMethods {{.*}} (struct method_list_t *)
84 ; MERGE_CATS-NEXT: optionalInstanceMethods {{.*}}
85 ; MERGE_CATS-NEXT: optionalClassMethods {{.*}}
86 ; MERGE_CATS-NEXT: instanceProperties {{.*}}
87 ; MERGE_CATS-NEXT: ivars {{.*}}
88 ; MERGE_CATS-NEXT: weakIvarLayout {{.*}}
89 ; MERGE_CATS-NEXT: baseProperties {{.*}}
90 ; MERGE_CATS-NEXT: Contents of (__DATA_CONST,__objc_protolist) section
91 ; MERGE_CATS-NEXT: {{.*}} {{.*}} __OBJC_PROTOCOL_$_MyTestProtocol
92 ; MERGE_CATS-NEXT: Contents of (__DATA_CONST,__objc_imageinfo) section
93 ; MERGE_CATS-NEXT: version 0
94 ; MERGE_CATS-NEXT: flags {{.*}} OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES
97 ; ================== repro.sh ====================
98 ; # Write the Objective-C code to a file
99 ; cat << EOF > MyClass.m
100 ; @protocol MyTestProtocol
104 ; __attribute__((objc_root_class))
105 ; @interface MyBaseClass
106 ; - (void)baseInstanceMethod;
109 ; @implementation MyBaseClass
110 ; - (void)baseInstanceMethod {}
113 ; @interface MyBaseClass (MyTestProtocol) <MyTestProtocol>
116 ; @implementation MyBaseClass (MyTestProtocol)
125 ; # Compile the Objective-C file to assembly
126 ; xcrun clang -S -arch arm64 MyClass.m -o MyClass.s
127 ; ==============================================
130 .section __TEXT,__text,regular,pure_instructions
131 .p2align 2 ; -- Begin function -[MyBaseClass baseInstanceMethod]
132 "-[MyBaseClass baseInstanceMethod]": ; @"\01-[MyBaseClass baseInstanceMethod]"
136 .cfi_def_cfa_offset 16
143 .p2align 2 ; -- Begin function -[MyBaseClass(MyTestProtocol) getValue]
144 "-[MyBaseClass(MyTestProtocol) getValue]": ; @"\01-[MyBaseClass(MyTestProtocol) getValue]"
148 .cfi_def_cfa_offset 16
156 .section __DATA,__objc_data
157 .globl _OBJC_CLASS_$_MyBaseClass ; @"OBJC_CLASS_$_MyBaseClass"
159 _OBJC_CLASS_$_MyBaseClass:
160 .quad _OBJC_METACLASS_$_MyBaseClass
162 .quad __objc_empty_cache
164 .quad __OBJC_CLASS_RO_$_MyBaseClass
165 .globl _OBJC_METACLASS_$_MyBaseClass ; @"OBJC_METACLASS_$_MyBaseClass"
167 _OBJC_METACLASS_$_MyBaseClass:
168 .quad _OBJC_METACLASS_$_MyBaseClass
169 .quad _OBJC_CLASS_$_MyBaseClass
170 .quad __objc_empty_cache
172 .quad __OBJC_METACLASS_RO_$_MyBaseClass
173 .section __TEXT,__objc_classname,cstring_literals
174 l_OBJC_CLASS_NAME_: ; @OBJC_CLASS_NAME_
176 .section __DATA,__objc_const
177 .p2align 3, 0x0 ; @"_OBJC_METACLASS_RO_$_MyBaseClass"
178 __OBJC_METACLASS_RO_$_MyBaseClass:
184 .quad l_OBJC_CLASS_NAME_
190 .section __TEXT,__objc_methname,cstring_literals
191 l_OBJC_METH_VAR_NAME_: ; @OBJC_METH_VAR_NAME_
192 .asciz "baseInstanceMethod"
193 .section __TEXT,__objc_methtype,cstring_literals
194 l_OBJC_METH_VAR_TYPE_: ; @OBJC_METH_VAR_TYPE_
196 .section __DATA,__objc_const
197 .p2align 3, 0x0 ; @"_OBJC_$_INSTANCE_METHODS_MyBaseClass"
198 __OBJC_$_INSTANCE_METHODS_MyBaseClass:
201 .quad l_OBJC_METH_VAR_NAME_
202 .quad l_OBJC_METH_VAR_TYPE_
203 .quad "-[MyBaseClass baseInstanceMethod]"
204 .p2align 3, 0x0 ; @"_OBJC_CLASS_RO_$_MyBaseClass"
205 __OBJC_CLASS_RO_$_MyBaseClass:
211 .quad l_OBJC_CLASS_NAME_
212 .quad __OBJC_$_INSTANCE_METHODS_MyBaseClass
217 .section __TEXT,__objc_classname,cstring_literals
218 l_OBJC_CLASS_NAME_.1: ; @OBJC_CLASS_NAME_.1
219 .asciz "MyTestProtocol"
220 .section __TEXT,__objc_methname,cstring_literals
221 l_OBJC_METH_VAR_NAME_.2: ; @OBJC_METH_VAR_NAME_.2
223 .section __TEXT,__objc_methtype,cstring_literals
224 l_OBJC_METH_VAR_TYPE_.3: ; @OBJC_METH_VAR_TYPE_.3
226 .section __DATA,__objc_const
227 .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol"
228 __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol:
231 .quad l_OBJC_METH_VAR_NAME_.2
232 .quad l_OBJC_METH_VAR_TYPE_.3
233 .quad "-[MyBaseClass(MyTestProtocol) getValue]"
234 .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol"
235 __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol:
238 .quad l_OBJC_METH_VAR_NAME_.2
239 .quad l_OBJC_METH_VAR_TYPE_.3
241 .p2align 3, 0x0 ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol"
242 __OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol:
243 .quad l_OBJC_METH_VAR_TYPE_.3
244 .private_extern __OBJC_PROTOCOL_$_MyTestProtocol ; @"_OBJC_PROTOCOL_$_MyTestProtocol"
245 .section __DATA,__data
246 .globl __OBJC_PROTOCOL_$_MyTestProtocol
247 .weak_definition __OBJC_PROTOCOL_$_MyTestProtocol
249 __OBJC_PROTOCOL_$_MyTestProtocol:
251 .quad l_OBJC_CLASS_NAME_.1
253 .quad __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol
260 .quad __OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol
263 .private_extern __OBJC_LABEL_PROTOCOL_$_MyTestProtocol ; @"_OBJC_LABEL_PROTOCOL_$_MyTestProtocol"
264 .section __DATA,__objc_protolist,coalesced,no_dead_strip
265 .globl __OBJC_LABEL_PROTOCOL_$_MyTestProtocol
266 .weak_definition __OBJC_LABEL_PROTOCOL_$_MyTestProtocol
268 __OBJC_LABEL_PROTOCOL_$_MyTestProtocol:
269 .quad __OBJC_PROTOCOL_$_MyTestProtocol
270 .section __DATA,__objc_const
271 .p2align 3, 0x0 ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol"
272 __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol:
274 .quad __OBJC_PROTOCOL_$_MyTestProtocol
276 .p2align 3, 0x0 ; @"_OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol"
277 __OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol:
278 .quad l_OBJC_CLASS_NAME_.1
279 .quad _OBJC_CLASS_$_MyBaseClass
280 .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol
282 .quad __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol
287 .section __DATA,__objc_classlist,regular,no_dead_strip
288 .p2align 3, 0x0 ; @"OBJC_LABEL_CLASS_$"
289 l_OBJC_LABEL_CLASS_$:
290 .quad _OBJC_CLASS_$_MyBaseClass
291 .section __DATA,__objc_catlist,regular,no_dead_strip
292 .p2align 3, 0x0 ; @"OBJC_LABEL_CATEGORY_$"
293 l_OBJC_LABEL_CATEGORY_$:
294 .quad __OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol
295 .no_dead_strip __OBJC_PROTOCOL_$_MyTestProtocol
296 .no_dead_strip __OBJC_LABEL_PROTOCOL_$_MyTestProtocol
297 .section __DATA,__objc_imageinfo,regular,no_dead_strip
306 .subsections_via_symbols