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 --defsym MAKE_LOAD_METHOD=1 -o %t/cat1-with-load.o
7 # 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
8 # 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
9 # 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
10 # RUN: %lld -dylib -lobjc %t/klass.o -o %t/libklass.dylib
12 # RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \
13 # RUN: /dev/null 2>&1 | FileCheck %s --check-prefixes=CATCLS,CATCAT
14 # RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/libklass.dylib %t/cat1.o \
15 # RUN: %t/cat2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT
17 ## Check that we don't emit spurious warnings around the +load method while
18 ## still emitting the other warnings. Note that we have made separate
19 ## `*-with-load.s` files for ease of comparison with ld64; ld64 will not warn
20 ## at all if multiple +load methods are present.
21 # RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/klass-with-load.o \
22 # RUN: %t/cat1-with-load.o %t/cat2-with-load.o -o /dev/null 2>&1 | \
23 # RUN: FileCheck %s --check-prefixes=CATCLS,CATCAT --implicit-check-not '+load'
25 ## Regression test: Check that we don't crash.
26 # RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/klass-with-no-rodata.o -o /dev/null
28 ## Check that we don't emit any warnings without --check-category-conflicts.
29 # RUN: %no-fatal-warnings-lld -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \
30 # RUN: /dev/null 2>&1 | FileCheck %s --implicit-check-not 'warning' --allow-empty
32 # CATCLS: warning: method '+s1' has conflicting definitions:
33 # CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
34 # CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass{{.*}}.o
36 # CATCLS: warning: method '-m1' has conflicting definitions:
37 # CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
38 # CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass{{.*}}.o
40 # CATCAT: warning: method '+s2' has conflicting definitions:
41 # CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o
42 # CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
44 # CATCAT: warning: method '-m2' has conflicting definitions:
45 # CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o
46 # CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
50 .include "objc-macros.s"
52 ## @interface Foo(Cat1)
59 ## @implementation Foo(Cat1)
66 .section __DATA,__objc_catlist,regular,no_dead_strip
67 .quad __OBJC_$_CATEGORY_Foo_$_Cat1
69 .ifdef MAKE_LOAD_METHOD
70 .section __DATA,__objc_nlcatlist,regular,no_dead_strip
71 .quad __OBJC_$_CATEGORY_Foo_$_Cat1
74 .section __DATA,__objc_const
75 __OBJC_$_CATEGORY_Foo_$_Cat1
:
76 .objc_classname "Cat1"
77 .quad _OBJC_CLASS_$_Foo
78 .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat1
79 .quad __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1
86 __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat1
:
87 .long 24 # size of method entry
88 .long 2 # number of methods
89 .empty_objc_method "m1", "v16@0:8", "-[Foo(Cat1) m1]"
90 .empty_objc_method "m2", "v16@0:8", "-[Foo(Cat2) m2]"
92 __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1
:
94 .ifdef MAKE_LOAD_METHOD
96 .empty_objc_method "load", "v16@0:8", "+[Foo(Cat1) load]"
100 .empty_objc_method "s1", "v16@0:8", "+[Foo(Cat1) s1]"
101 .empty_objc_method "s2", "v16@0:8", "+[Foo(Cat1) s2]"
103 .section __DATA,__objc_imageinfo,regular,no_dead_strip
107 .subsections_via_symbols
111 .include "objc-macros.s"
113 ## @interface Foo(Cat2)
118 ## @implementation Foo(Cat2)
123 .section __DATA,__objc_catlist,regular,no_dead_strip
124 .quad __OBJC_$_CATEGORY_Foo_$_Cat2
126 .ifdef MAKE_LOAD_METHOD
127 .section __DATA,__objc_nlcatlist,regular,no_dead_strip
128 .quad __OBJC_$_CATEGORY_Foo_$_Cat2
131 .section __DATA,__objc_const
132 __OBJC_$_CATEGORY_Foo_$_Cat2
:
133 .objc_classname "Cat2"
134 .quad _OBJC_CLASS_$_Foo
135 .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat2
136 .quad __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat2
143 __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat2
:
146 .empty_objc_method "m2", "v16@0:8", "-[Foo(Cat2) m2]"
148 __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat2
:
150 .ifdef MAKE_LOAD_METHOD
152 .empty_objc_method "load", "v16@0:8", "+[Foo(Cat2) load]"
156 .empty_objc_method "s2", "v16@0:8", "+[Foo(Cat2) m2]"
158 .section __DATA,__objc_imageinfo,regular,no_dead_strip
162 .subsections_via_symbols
166 .include "objc-macros.s"
173 ## @implementation Foo
178 .globl _OBJC_CLASS_$_Foo, _OBJC_METACLASS_$_Foo
180 .section __DATA,__objc_data
182 .quad _OBJC_METACLASS_$_Foo
184 .quad __objc_empty_cache
186 .quad __OBJC_CLASS_RO_$_Foo
188 _OBJC_METACLASS_$_Foo
:
189 .quad _OBJC_METACLASS_$_Foo
190 .quad _OBJC_CLASS_$_Foo
191 .quad __objc_empty_cache
193 .quad __OBJC_METACLASS_RO_$_Foo
195 .section __DATA,__objc_const
196 __OBJC_METACLASS_RO_$_Foo
:
202 .objc_classname "Foo"
203 .quad __OBJC_$_CLASS_METHODS_Foo
209 __OBJC_CLASS_RO_$_Foo
:
215 .objc_classname "Foo"
216 .quad __OBJC_$_INSTANCE_METHODS_Foo
222 __OBJC_$_CLASS_METHODS_Foo
:
224 .ifdef MAKE_LOAD_METHOD
226 .empty_objc_method "load", "v16@0:8", "+[Foo load]"
230 .empty_objc_method "s1", "v16@0:8", "+[Foo s1]"
232 __OBJC_$_INSTANCE_METHODS_Foo
:
235 .empty_objc_method "m1", "v16@0:8", "-[Foo m1]"
237 .section __DATA,__objc_classlist,regular,no_dead_strip
238 .quad _OBJC_CLASS_$_Foo
240 .ifdef MAKE_LOAD_METHOD
241 .section __DATA,__objc_nlclslist,regular,no_dead_strip
242 .quad _OBJC_CLASS_$_Foo
245 .section __DATA,__objc_imageinfo,regular,no_dead_strip
249 .subsections_via_symbols
251 #--- klass-with-no-rodata.s
253 .include "objc-macros.s"
255 ## swiftc generates some classes without a statically-linked rodata. Not
256 ## entirely sure what the corresponding Swift inputs are required for this to
257 ## happen; this test merely checks that we can gracefully handle this case
259 ## FIXME: It would be better if this test used the output of some real Swift
264 .section __DATA,__objc_data
268 .quad __objc_empty_cache
270 .quad __objc_empty_cache
272 .section __DATA,__objc_catlist,regular,no_dead_strip
273 .quad __CATEGORY_METAFoo_$_Foo20
275 .section __DATA,__objc_const
276 __CATEGORY_METAFoo_$_Foo20
:
277 .objc_classname "Foo20"
289 # Macros for taking some of the boilerplate out of defining objc structs.
291 # NOTE: \@ below is a variable that gets auto-incremented by the assembler on
292 # each macro invocation. It serves as a mechanism for generating unique symbol
293 # names for each macro call.
295 .macro .objc_classname name
297 .section __TEXT,__objc_classname,cstring_literals
298 L_OBJC_CLASS_NAME_.\@
:
301 .section __DATA,__objc_const
302 .quad L_OBJC_CLASS_NAME_.\@
311 .macro .objc_method name, type, impl
313 .section __TEXT,__objc_methname,cstring_literals
314 L_OBJC_METH_VAR_NAME_.\@
:
317 .section __TEXT,__objc_methtype,cstring_literals
318 L_OBJC_METH_VAR_TYPE_.\@
:
321 .section __DATA,__objc_const
322 .quad L_OBJC_METH_VAR_NAME_.\@
323 .quad L_OBJC_METH_VAR_TYPE_.\@
328 # Generate a method_t with a basic impl that just contains `ret`.
329 .macro .empty_objc_method name, type, impl
335 .objc_method "\name", "\type", "\impl"