2 # RUN: rm -rf %t; split-file %s %t
3 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -o %t/cat1.o
4 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -o %t/cat2.o
5 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -o %t/klass.o
6 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -g -o %t/cat1_w_sym.o
7 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -g -o %t/cat2_w_sym.o
8 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -g -o %t/klass_w_sym.o
9 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s --defsym MAKE_LOAD_METHOD=1 -o %t/cat1-with-load.o
10 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s --defsym MAKE_LOAD_METHOD=1 -o %t/cat2-with-load.o
11 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s --defsym MAKE_LOAD_METHOD=1 -o %t/klass-with-load.o
12 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass-with-no-rodata.s -o %t/klass-with-no-rodata.o
13 # RUN: %lld -no_objc_relative_method_lists -dylib -lobjc %t/klass.o -o %t/libklass.dylib
15 # RUN: %no-fatal-warnings-lld -no_objc_relative_method_lists --check-category-conflicts -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \
16 # RUN: /dev/null 2>&1 | FileCheck %s --check-prefixes=CATCLS,CATCAT
17 # RUN: %no-fatal-warnings-lld -no_objc_relative_method_lists --check-category-conflicts -dylib -lobjc %t/libklass.dylib %t/cat1.o \
18 # RUN: %t/cat2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT
20 # RUN: %no-fatal-warnings-lld -no_objc_relative_method_lists --check-category-conflicts -dylib -lobjc %t/klass_w_sym.o %t/cat1_w_sym.o %t/cat2_w_sym.o -o \
21 # RUN: /dev/null 2>&1 | FileCheck %s --check-prefixes=CATCLS_W_SYM,CATCAT_W_SYM
22 # RUN: %no-fatal-warnings-lld -no_objc_relative_method_lists --check-category-conflicts -dylib -lobjc %t/libklass.dylib %t/cat1_w_sym.o \
23 # RUN: %t/cat2_w_sym.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT_W_SYM
25 ## Check that we don't emit spurious warnings around the +load method while
26 ## still emitting the other warnings. Note that we have made separate
27 ## `*-with-load.s` files for ease of comparison with ld64; ld64 will not warn
28 ## at all if multiple +load methods are present.
29 # RUN: %no-fatal-warnings-lld -no_objc_relative_method_lists --check-category-conflicts -dylib -lobjc %t/klass-with-load.o \
30 # RUN: %t/cat1-with-load.o %t/cat2-with-load.o -o /dev/null 2>&1 | \
31 # RUN: FileCheck %s --check-prefixes=CATCLS,CATCAT --implicit-check-not '+load'
33 ## Regression test: Check that we don't crash.
34 # RUN: %no-fatal-warnings-lld -no_objc_relative_method_lists --check-category-conflicts -dylib -lobjc %t/klass-with-no-rodata.o -o /dev/null
36 ## Check that we don't emit any warnings without --check-category-conflicts.
37 # RUN: %no-fatal-warnings-lld -no_objc_relative_method_lists -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \
38 # RUN: /dev/null 2>&1 | FileCheck %s --implicit-check-not 'warning' --allow-empty
40 # CATCLS: warning: method '+s1' has conflicting definitions:
41 # CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
42 # CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass{{.*}}.o
44 # CATCLS: warning: method '-m1' has conflicting definitions:
45 # CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
46 # CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass{{.*}}.o
48 # CATCAT: warning: method '+s2' has conflicting definitions:
49 # CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o
50 # CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
52 # CATCAT: warning: method '-m2' has conflicting definitions:
53 # CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o
54 # CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
57 # CATCLS_W_SYM: warning: method '+s1' has conflicting definitions:
58 # CATCLS_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
59 # CATCLS_W_SYM-NEXT: >>> defined in class Foo from {{.*}}klass_w_sym{{.*}}.o ({{.*}}klass.s{{.*}})
61 # CATCLS_W_SYM: warning: method '-m1' has conflicting definitions:
62 # CATCLS_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
63 # CATCLS_W_SYM-NEXT: >>> defined in class Foo from {{.*}}klass_w_sym{{.*}}.o ({{.*}}klass.s{{.*}})
65 # CATCAT_W_SYM: warning: method '+s2' has conflicting definitions:
66 # CATCAT_W_SYM-NEXT: >>> defined in category Cat2 from {{.*}}cat2_w_sym{{.*}}.o ({{.*}}cat2.s{{.*}})
67 # CATCAT_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
69 # CATCAT_W_SYM: warning: method '-m2' has conflicting definitions:
70 # CATCAT_W_SYM-NEXT: >>> defined in category Cat2 from {{.*}}cat2_w_sym{{.*}}.o ({{.*}}cat2.s{{.*}})
71 # CATCAT_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}})
76 .include "objc-macros.s"
78 ## @interface Foo(Cat1)
85 ## @implementation Foo(Cat1)
92 .section __DATA,__objc_catlist,regular,no_dead_strip
93 .quad __OBJC_$_CATEGORY_Foo_$_Cat1
95 .ifdef MAKE_LOAD_METHOD
96 .section __DATA,__objc_nlcatlist,regular,no_dead_strip
97 .quad __OBJC_$_CATEGORY_Foo_$_Cat1
100 .section __DATA,__objc_const
101 __OBJC_$_CATEGORY_Foo_$_Cat1
:
102 .objc_classname "Cat1"
103 .quad _OBJC_CLASS_$_Foo
104 .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat1
105 .quad __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1
112 __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat1
:
113 .long 24 # size of method entry
114 .long 2 # number of methods
115 .empty_objc_method "m1", "v16@0:8", "-[Foo(Cat1) m1]"
116 .empty_objc_method "m2", "v16@0:8", "-[Foo(Cat2) m2]"
118 __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1
:
120 .ifdef MAKE_LOAD_METHOD
122 .empty_objc_method "load", "v16@0:8", "+[Foo(Cat1) load]"
126 .empty_objc_method "s1", "v16@0:8", "+[Foo(Cat1) s1]"
127 .empty_objc_method "s2", "v16@0:8", "+[Foo(Cat1) s2]"
129 .section __DATA,__objc_imageinfo,regular,no_dead_strip
133 .subsections_via_symbols
137 .include "objc-macros.s"
139 ## @interface Foo(Cat2)
144 ## @implementation Foo(Cat2)
149 .section __DATA,__objc_catlist,regular,no_dead_strip
150 .quad __OBJC_$_CATEGORY_Foo_$_Cat2
152 .ifdef MAKE_LOAD_METHOD
153 .section __DATA,__objc_nlcatlist,regular,no_dead_strip
154 .quad __OBJC_$_CATEGORY_Foo_$_Cat2
157 .section __DATA,__objc_const
158 __OBJC_$_CATEGORY_Foo_$_Cat2
:
159 .objc_classname "Cat2"
160 .quad _OBJC_CLASS_$_Foo
161 .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat2
162 .quad __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat2
169 __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat2
:
172 .empty_objc_method "m2", "v16@0:8", "-[Foo(Cat2) m2]"
174 __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat2
:
176 .ifdef MAKE_LOAD_METHOD
178 .empty_objc_method "load", "v16@0:8", "+[Foo(Cat2) load]"
182 .empty_objc_method "s2", "v16@0:8", "+[Foo(Cat2) m2]"
184 .section __DATA,__objc_imageinfo,regular,no_dead_strip
188 .subsections_via_symbols
192 .include "objc-macros.s"
199 ## @implementation Foo
204 .globl _OBJC_CLASS_$_Foo, _OBJC_METACLASS_$_Foo
206 .section __DATA,__objc_data
208 .quad _OBJC_METACLASS_$_Foo
210 .quad __objc_empty_cache
212 .quad __OBJC_CLASS_RO_$_Foo
214 _OBJC_METACLASS_$_Foo
:
215 .quad _OBJC_METACLASS_$_Foo
216 .quad _OBJC_CLASS_$_Foo
217 .quad __objc_empty_cache
219 .quad __OBJC_METACLASS_RO_$_Foo
221 .section __DATA,__objc_const
222 __OBJC_METACLASS_RO_$_Foo
:
228 .objc_classname "Foo"
229 .quad __OBJC_$_CLASS_METHODS_Foo
235 __OBJC_CLASS_RO_$_Foo
:
241 .objc_classname "Foo"
242 .quad __OBJC_$_INSTANCE_METHODS_Foo
248 __OBJC_$_CLASS_METHODS_Foo
:
250 .ifdef MAKE_LOAD_METHOD
252 .empty_objc_method "load", "v16@0:8", "+[Foo load]"
256 .empty_objc_method "s1", "v16@0:8", "+[Foo s1]"
258 __OBJC_$_INSTANCE_METHODS_Foo
:
261 .empty_objc_method "m1", "v16@0:8", "-[Foo m1]"
263 .section __DATA,__objc_classlist,regular,no_dead_strip
264 .quad _OBJC_CLASS_$_Foo
266 .ifdef MAKE_LOAD_METHOD
267 .section __DATA,__objc_nlclslist,regular,no_dead_strip
268 .quad _OBJC_CLASS_$_Foo
271 .section __DATA,__objc_imageinfo,regular,no_dead_strip
275 .subsections_via_symbols
277 #--- klass-with-no-rodata.s
279 .include "objc-macros.s"
281 ## swiftc generates some classes without a statically-linked rodata. Not
282 ## entirely sure what the corresponding Swift inputs are required for this to
283 ## happen; this test merely checks that we can gracefully handle this case
285 ## FIXME: It would be better if this test used the output of some real Swift
290 .section __DATA,__objc_data
294 .quad __objc_empty_cache
296 .quad __objc_empty_cache
298 .section __DATA,__objc_catlist,regular,no_dead_strip
299 .quad __CATEGORY_METAFoo_$_Foo20
301 .section __DATA,__objc_const
302 __CATEGORY_METAFoo_$_Foo20
:
303 .objc_classname "Foo20"
315 # Macros for taking some of the boilerplate out of defining objc structs.
317 # NOTE: \@ below is a variable that gets auto-incremented by the assembler on
318 # each macro invocation. It serves as a mechanism for generating unique symbol
319 # names for each macro call.
321 .macro .objc_classname name
323 .section __TEXT,__objc_classname,cstring_literals
324 L_OBJC_CLASS_NAME_.\@
:
327 .section __DATA,__objc_const
328 .quad L_OBJC_CLASS_NAME_.\@
337 .macro .objc_method name, type, impl
339 .section __TEXT,__objc_methname,cstring_literals
340 L_OBJC_METH_VAR_NAME_.\@
:
343 .section __TEXT,__objc_methtype,cstring_literals
344 L_OBJC_METH_VAR_TYPE_.\@
:
347 .section __DATA,__objc_const
348 .quad L_OBJC_METH_VAR_NAME_.\@
349 .quad L_OBJC_METH_VAR_TYPE_.\@
354 # Generate a method_t with a basic impl that just contains `ret`.
355 .macro .empty_objc_method name, type, impl
361 .objc_method "\name", "\type", "\impl"