[lld] [lld-macho] Fix erasing category names for ObjC categories (PR #99400)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 19 16:58:01 PDT 2024


https://github.com/alx32 updated https://github.com/llvm/llvm-project/pull/99400

>From 06f375cbeb8a45b056d8e701e6935ca0c43f10f8 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Wed, 10 Jul 2024 16:42:39 -0700
Subject: [PATCH 1/2] [lld-macho] Fix erasing category names for ObjC
 categories

---
 lld/MachO/ObjC.cpp                            |  16 +-
 ...jc-category-merging-erase-objc-name-test.s | 306 ++++++++++++++++++
 2 files changed, 317 insertions(+), 5 deletions(-)
 create mode 100644 lld/test/MachO/objc-category-merging-erase-objc-name-test.s

diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index 4a6f99654ba13..0787092f4facf 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -1303,12 +1303,18 @@ void ObjcCategoryMerger::eraseMergedCategories() {
         continue;
 
       eraseISec(catInfo.catBodyIsec);
-      // We can't erase 'catLayout.nameOffset' for Swift categories because the
-      // name will be referenced for generating relative offsets
-      // See usages of 'l_.str.11.SimpleClass' in objc-category-merging-swift.s
+
+      // We can't erase 'catLayout.nameOffset' for either Swift or ObjC
+      //   categories because the name will sometimes also be used for other
+      //   purposes.
+      // For Swift, see  usages of 'l_.str.11.SimpleClass' in
+      //   objc-category-merging-swift.s
+      // For ObjC, see usages of 'l_OBJC_CLASS_NAME_.1' in
+      //   objc-category-merging-erase-objc-name-test.s
       // TODO: handle the above in a smarter way
-      if (catInfo.sourceLanguage != SourceLanguage::Swift)
-        tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
+
+      // tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
+
       tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
                                   catLayout.instanceMethodsOffset);
       tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
diff --git a/lld/test/MachO/objc-category-merging-erase-objc-name-test.s b/lld/test/MachO/objc-category-merging-erase-objc-name-test.s
new file mode 100644
index 0000000000000..7f5753705c30d
--- /dev/null
+++ b/lld/test/MachO/objc-category-merging-erase-objc-name-test.s
@@ -0,0 +1,306 @@
+# REQUIRES: aarch64
+
+
+### Here we test that if we defined a protocl MyTestProtocol and also a category MyTestProtocol
+### then when merging the category into the base class (and deleting the category), we don't
+### delete the 'MyTestProtocol' name
+
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o erase-objc-name.o %s
+# RUN: %lld -arch arm64 -dylib -o erase-objc-name.dylib erase-objc-name.o -objc_category_merging
+# RUN: llvm-objdump --objc-meta-data --macho erase-objc-name.dylib | FileCheck %s --check-prefixes=MERGE_CATS
+
+#### Check merge categories enabled ###
+# Check that the original categories are not there
+# MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01
+# MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
+
+# Check that we get the expected output - most importantly that the protocol is named `MyTestProtocol`
+; MERGE_CATS:        Contents of (__DATA_CONST,__objc_classlist) section
+; MERGE_CATS-NEXT:   _OBJC_CLASS_$_MyBaseClass
+; MERGE_CATS-NEXT:            isa {{.*}} _OBJC_METACLASS_$_MyBaseClass
+; MERGE_CATS-NEXT:     superclass {{.*}}
+; MERGE_CATS-NEXT:          cache {{.*}}
+; MERGE_CATS-NEXT:         vtable {{.*}}
+; MERGE_CATS-NEXT:           data {{.*}} (struct class_ro_t *)
+; MERGE_CATS-NEXT:                     flags {{.*}} RO_ROOT
+; MERGE_CATS-NEXT:             instanceStart 0
+; MERGE_CATS-NEXT:              instanceSize 0
+; MERGE_CATS-NEXT:                  reserved {{.*}}
+; MERGE_CATS-NEXT:                ivarLayout {{.*}}
+; MERGE_CATS-NEXT:                      name {{.*}} MyBaseClass
+; MERGE_CATS-NEXT:               baseMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT: 		   entsize 24
+; MERGE_CATS-NEXT: 		     count 2
+; MERGE_CATS-NEXT: 		      name {{.*}} getValue
+; MERGE_CATS-NEXT: 		     types {{.*}} i16 at 0:8
+; MERGE_CATS-NEXT: 		       imp -[MyBaseClass(MyTestProtocol) getValue]
+; MERGE_CATS-NEXT: 		      name {{.*}} baseInstanceMethod
+; MERGE_CATS-NEXT: 		     types {{.*}} v16 at 0:8
+; MERGE_CATS-NEXT: 		       imp -[MyBaseClass baseInstanceMethod]
+; MERGE_CATS-NEXT:             baseProtocols {{.*}}
+; MERGE_CATS-NEXT:                       count 1
+; MERGE_CATS-NEXT: 		      list[0] {{.*}} (struct protocol_t *)
+; MERGE_CATS-NEXT: 			      isa {{.*}}
+; MERGE_CATS-NEXT: 			     name {{.*}} MyTestProtocol
+; MERGE_CATS-NEXT: 			protocols {{.*}}
+; MERGE_CATS-NEXT: 		  instanceMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT: 			   entsize 24
+; MERGE_CATS-NEXT: 			     count 1
+; MERGE_CATS-NEXT: 			      name {{.*}} getValue
+; MERGE_CATS-NEXT: 			     types {{.*}} i16 at 0:8
+; MERGE_CATS-NEXT: 			       imp {{.*}}
+; MERGE_CATS-NEXT: 		     classMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT: 	  optionalInstanceMethods {{.*}}
+; MERGE_CATS-NEXT: 	     optionalClassMethods {{.*}}
+; MERGE_CATS-NEXT: 	       instanceProperties {{.*}}
+; MERGE_CATS-NEXT:                     ivars {{.*}}
+; MERGE_CATS-NEXT:            weakIvarLayout {{.*}}
+; MERGE_CATS-NEXT:            baseProperties {{.*}}
+; MERGE_CATS-NEXT: Meta Class
+; MERGE_CATS-NEXT:            isa {{.*}} _OBJC_METACLASS_$_MyBaseClass
+; MERGE_CATS-NEXT:     superclass {{.*}} _OBJC_CLASS_$_MyBaseClass
+; MERGE_CATS-NEXT:          cache {{.*}}
+; MERGE_CATS-NEXT:         vtable {{.*}}
+; MERGE_CATS-NEXT:           data {{.*}} (struct class_ro_t *)
+; MERGE_CATS-NEXT:                     flags {{.*}} RO_META RO_ROOT
+; MERGE_CATS-NEXT:             instanceStart 40
+; MERGE_CATS-NEXT:              instanceSize 40
+; MERGE_CATS-NEXT:                  reserved {{.*}}
+; MERGE_CATS-NEXT:                ivarLayout {{.*}}
+; MERGE_CATS-NEXT:                      name {{.*}} MyBaseClass
+; MERGE_CATS-NEXT:               baseMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT:             baseProtocols {{.*}}
+; MERGE_CATS-NEXT:                       count 1
+; MERGE_CATS-NEXT: 		      list[0] {{.*}} (struct protocol_t *)
+; MERGE_CATS-NEXT: 			      isa {{.*}}
+; MERGE_CATS-NEXT: 			     name {{.*}} MyTestProtocol
+; MERGE_CATS-NEXT: 			protocols {{.*}}
+; MERGE_CATS-NEXT: 		  instanceMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT: 			   entsize 24
+; MERGE_CATS-NEXT: 			     count 1
+; MERGE_CATS-NEXT: 			      name {{.*}} getValue
+; MERGE_CATS-NEXT: 			     types {{.*}} i16 at 0:8
+; MERGE_CATS-NEXT: 			       imp {{.*}}
+; MERGE_CATS-NEXT: 		     classMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT: 	  optionalInstanceMethods {{.*}}
+; MERGE_CATS-NEXT: 	     optionalClassMethods {{.*}}
+; MERGE_CATS-NEXT: 	       instanceProperties {{.*}}
+; MERGE_CATS-NEXT:                     ivars {{.*}}
+; MERGE_CATS-NEXT:            weakIvarLayout {{.*}}
+; MERGE_CATS-NEXT:            baseProperties {{.*}}
+; MERGE_CATS-NEXT: Contents of (__DATA_CONST,__objc_protolist) section
+; MERGE_CATS-NEXT: {{.*}} {{.*}} __OBJC_PROTOCOL_$_MyTestProtocol
+; MERGE_CATS-NEXT: Contents of (__DATA_CONST,__objc_imageinfo) section
+; MERGE_CATS-NEXT:   version 0
+; MERGE_CATS-NEXT:     flags {{.*}} OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES
+
+
+; ================== repro.sh ====================
+; # Write the Objective-C code to a file
+; cat << EOF > MyClass.m
+; @protocol MyTestProtocol
+; - (int)getValue;
+; @end
+;
+; __attribute__((objc_root_class))
+; @interface MyBaseClass
+; - (void)baseInstanceMethod;
+; @end
+;
+; @implementation MyBaseClass
+; - (void)baseInstanceMethod {}
+; @end
+;
+; @interface MyBaseClass (MyTestProtocol) <MyTestProtocol>
+; @end
+;
+; @implementation MyBaseClass (MyTestProtocol)
+;
+; - (int)getValue {
+;     return 0x30;
+; }
+;
+; @end
+; EOF
+;
+; # Compile the Objective-C file to assembly
+; xcrun clang -S -arch arm64 MyClass.m -o MyClass.s
+
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.p2align	2                               ; -- Begin function -[MyBaseClass baseInstanceMethod]
+"-[MyBaseClass baseInstanceMethod]":    ; @"\01-[MyBaseClass baseInstanceMethod]"
+	.cfi_startproc
+; %bb.0:
+	sub	sp, sp, #16
+	.cfi_def_cfa_offset 16
+	str	x0, [sp, #8]
+	str	x1, [sp]
+	add	sp, sp, #16
+	ret
+	.cfi_endproc
+                                        ; -- End function
+	.p2align	2                               ; -- Begin function -[MyBaseClass(MyTestProtocol) getValue]
+"-[MyBaseClass(MyTestProtocol) getValue]": ; @"\01-[MyBaseClass(MyTestProtocol) getValue]"
+	.cfi_startproc
+; %bb.0:
+	sub	sp, sp, #16
+	.cfi_def_cfa_offset 16
+	str	x0, [sp, #8]
+	str	x1, [sp]
+	mov	w0, #48                         ; =0x30
+	add	sp, sp, #16
+	ret
+	.cfi_endproc
+                                        ; -- End function
+	.section	__DATA,__objc_data
+	.globl	_OBJC_CLASS_$_MyBaseClass       ; @"OBJC_CLASS_$_MyBaseClass"
+	.p2align	3, 0x0
+_OBJC_CLASS_$_MyBaseClass:
+	.quad	_OBJC_METACLASS_$_MyBaseClass
+	.quad	0
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__OBJC_CLASS_RO_$_MyBaseClass
+	.globl	_OBJC_METACLASS_$_MyBaseClass   ; @"OBJC_METACLASS_$_MyBaseClass"
+	.p2align	3, 0x0
+_OBJC_METACLASS_$_MyBaseClass:
+	.quad	_OBJC_METACLASS_$_MyBaseClass
+	.quad	_OBJC_CLASS_$_MyBaseClass
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__OBJC_METACLASS_RO_$_MyBaseClass
+	.section	__TEXT,__objc_classname,cstring_literals
+l_OBJC_CLASS_NAME_:                     ; @OBJC_CLASS_NAME_
+	.asciz	"MyBaseClass"
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0                          ; @"_OBJC_METACLASS_RO_$_MyBaseClass"
+__OBJC_METACLASS_RO_$_MyBaseClass:
+	.long	131                             ; 0x83
+	.long	40                              ; 0x28
+	.long	40                              ; 0x28
+	.space	4
+	.quad	0
+	.quad	l_OBJC_CLASS_NAME_
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.section	__TEXT,__objc_methname,cstring_literals
+l_OBJC_METH_VAR_NAME_:                  ; @OBJC_METH_VAR_NAME_
+	.asciz	"baseInstanceMethod"
+	.section	__TEXT,__objc_methtype,cstring_literals
+l_OBJC_METH_VAR_TYPE_:                  ; @OBJC_METH_VAR_TYPE_
+	.asciz	"v16 at 0:8"
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0                          ; @"_OBJC_$_INSTANCE_METHODS_MyBaseClass"
+__OBJC_$_INSTANCE_METHODS_MyBaseClass:
+	.long	24                              ; 0x18
+	.long	1                               ; 0x1
+	.quad	l_OBJC_METH_VAR_NAME_
+	.quad	l_OBJC_METH_VAR_TYPE_
+	.quad	"-[MyBaseClass baseInstanceMethod]"
+	.p2align	3, 0x0                          ; @"_OBJC_CLASS_RO_$_MyBaseClass"
+__OBJC_CLASS_RO_$_MyBaseClass:
+	.long	130                             ; 0x82
+	.long	0                               ; 0x0
+	.long	0                               ; 0x0
+	.space	4
+	.quad	0
+	.quad	l_OBJC_CLASS_NAME_
+	.quad	__OBJC_$_INSTANCE_METHODS_MyBaseClass
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.section	__TEXT,__objc_classname,cstring_literals
+l_OBJC_CLASS_NAME_.1:                   ; @OBJC_CLASS_NAME_.1
+	.asciz	"MyTestProtocol"
+	.section	__TEXT,__objc_methname,cstring_literals
+l_OBJC_METH_VAR_NAME_.2:                ; @OBJC_METH_VAR_NAME_.2
+	.asciz	"getValue"
+	.section	__TEXT,__objc_methtype,cstring_literals
+l_OBJC_METH_VAR_TYPE_.3:                ; @OBJC_METH_VAR_TYPE_.3
+	.asciz	"i16 at 0:8"
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol"
+__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol:
+	.long	24                              ; 0x18
+	.long	1                               ; 0x1
+	.quad	l_OBJC_METH_VAR_NAME_.2
+	.quad	l_OBJC_METH_VAR_TYPE_.3
+	.quad	"-[MyBaseClass(MyTestProtocol) getValue]"
+	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol"
+__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol:
+	.long	24                              ; 0x18
+	.long	1                               ; 0x1
+	.quad	l_OBJC_METH_VAR_NAME_.2
+	.quad	l_OBJC_METH_VAR_TYPE_.3
+	.quad	0
+	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol"
+__OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol:
+	.quad	l_OBJC_METH_VAR_TYPE_.3
+	.private_extern	__OBJC_PROTOCOL_$_MyTestProtocol ; @"_OBJC_PROTOCOL_$_MyTestProtocol"
+	.section	__DATA,__data
+	.globl	__OBJC_PROTOCOL_$_MyTestProtocol
+	.weak_definition	__OBJC_PROTOCOL_$_MyTestProtocol
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_$_MyTestProtocol:
+	.quad	0
+	.quad	l_OBJC_CLASS_NAME_.1
+	.quad	0
+	.quad	__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.long	96                              ; 0x60
+	.long	0                               ; 0x0
+	.quad	__OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol
+	.quad	0
+	.quad	0
+	.private_extern	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol ; @"_OBJC_LABEL_PROTOCOL_$_MyTestProtocol"
+	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
+	.globl	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol
+	.weak_definition	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol
+	.p2align	3, 0x0
+__OBJC_LABEL_PROTOCOL_$_MyTestProtocol:
+	.quad	__OBJC_PROTOCOL_$_MyTestProtocol
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0                          ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol"
+__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol:
+	.quad	1                               ; 0x1
+	.quad	__OBJC_PROTOCOL_$_MyTestProtocol
+	.quad	0
+	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol"
+__OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol:
+	.quad	l_OBJC_CLASS_NAME_.1
+	.quad	_OBJC_CLASS_$_MyBaseClass
+	.quad	__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol
+	.quad	0
+	.quad	__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol
+	.quad	0
+	.quad	0
+	.long	64                              ; 0x40
+	.space	4
+	.section	__DATA,__objc_classlist,regular,no_dead_strip
+	.p2align	3, 0x0                          ; @"OBJC_LABEL_CLASS_$"
+l_OBJC_LABEL_CLASS_$:
+	.quad	_OBJC_CLASS_$_MyBaseClass
+	.section	__DATA,__objc_catlist,regular,no_dead_strip
+	.p2align	3, 0x0                          ; @"OBJC_LABEL_CATEGORY_$"
+l_OBJC_LABEL_CATEGORY_$:
+	.quad	__OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol
+	.no_dead_strip	__OBJC_PROTOCOL_$_MyTestProtocol
+	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	64
+
+__objc_empty_cache:
+_$sBOWV:
+  .quad 0
+
+.subsections_via_symbols

>From 06aa27253c9aae2318bcdc3e96e5625edeb3d95a Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Fri, 19 Jul 2024 16:51:18 -0700
Subject: [PATCH 2/2] Address Feedback nr.1

---
 lld/MachO/ObjC.cpp                            |   2 -
 ...jc-category-merging-erase-objc-name-test.s | 385 +++++++++---------
 2 files changed, 193 insertions(+), 194 deletions(-)

diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index 0787092f4facf..b06821faf1428 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -1313,8 +1313,6 @@ void ObjcCategoryMerger::eraseMergedCategories() {
       //   objc-category-merging-erase-objc-name-test.s
       // TODO: handle the above in a smarter way
 
-      // tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
-
       tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
                                   catLayout.instanceMethodsOffset);
       tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
diff --git a/lld/test/MachO/objc-category-merging-erase-objc-name-test.s b/lld/test/MachO/objc-category-merging-erase-objc-name-test.s
index 7f5753705c30d..4bc0621fe1157 100644
--- a/lld/test/MachO/objc-category-merging-erase-objc-name-test.s
+++ b/lld/test/MachO/objc-category-merging-erase-objc-name-test.s
@@ -1,20 +1,20 @@
-# REQUIRES: aarch64
+; REQUIRES: aarch64
 
 
-### Here we test that if we defined a protocl MyTestProtocol and also a category MyTestProtocol
-### then when merging the category into the base class (and deleting the category), we don't
-### delete the 'MyTestProtocol' name
+; Here we test that if we defined a protocl MyTestProtocol and also a category MyTestProtocol
+; then when merging the category into the base class (and deleting the category), we don't
+; delete the 'MyTestProtocol' name
 
-# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o erase-objc-name.o %s
-# RUN: %lld -arch arm64 -dylib -o erase-objc-name.dylib erase-objc-name.o -objc_category_merging
-# RUN: llvm-objdump --objc-meta-data --macho erase-objc-name.dylib | FileCheck %s --check-prefixes=MERGE_CATS
+; RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o erase-objc-name.o %s
+; RUN: %lld -arch arm64 -dylib -o erase-objc-name.dylib erase-objc-name.o -objc_category_merging
+; RUN: llvm-objdump --objc-meta-data --macho erase-objc-name.dylib | FileCheck %s --check-prefixes=MERGE_CATS
 
-#### Check merge categories enabled ###
-# Check that the original categories are not there
-# MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01
-# MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
+; === Check merge categories enabled ===
+; Check that the original categories are not there
+; MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category01
+; MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
 
-# Check that we get the expected output - most importantly that the protocol is named `MyTestProtocol`
+; Check that we get the expected output - most importantly that the protocol is named `MyTestProtocol`
 ; MERGE_CATS:        Contents of (__DATA_CONST,__objc_classlist) section
 ; MERGE_CATS-NEXT:   _OBJC_CLASS_$_MyBaseClass
 ; MERGE_CATS-NEXT:            isa {{.*}} _OBJC_METACLASS_$_MyBaseClass
@@ -29,30 +29,30 @@
 ; MERGE_CATS-NEXT:                ivarLayout {{.*}}
 ; MERGE_CATS-NEXT:                      name {{.*}} MyBaseClass
 ; MERGE_CATS-NEXT:               baseMethods {{.*}} (struct method_list_t *)
-; MERGE_CATS-NEXT: 		   entsize 24
-; MERGE_CATS-NEXT: 		     count 2
-; MERGE_CATS-NEXT: 		      name {{.*}} getValue
-; MERGE_CATS-NEXT: 		     types {{.*}} i16 at 0:8
-; MERGE_CATS-NEXT: 		       imp -[MyBaseClass(MyTestProtocol) getValue]
-; MERGE_CATS-NEXT: 		      name {{.*}} baseInstanceMethod
-; MERGE_CATS-NEXT: 		     types {{.*}} v16 at 0:8
-; MERGE_CATS-NEXT: 		       imp -[MyBaseClass baseInstanceMethod]
+; MERGE_CATS-NEXT:             entsize 24
+; MERGE_CATS-NEXT:               count 2
+; MERGE_CATS-NEXT:                name {{.*}} getValue
+; MERGE_CATS-NEXT:               types {{.*}} i16 at 0:8
+; MERGE_CATS-NEXT:                 imp -[MyBaseClass(MyTestProtocol) getValue]
+; MERGE_CATS-NEXT:                name {{.*}} baseInstanceMethod
+; MERGE_CATS-NEXT:               types {{.*}} v16 at 0:8
+; MERGE_CATS-NEXT:                 imp -[MyBaseClass baseInstanceMethod]
 ; MERGE_CATS-NEXT:             baseProtocols {{.*}}
 ; MERGE_CATS-NEXT:                       count 1
-; MERGE_CATS-NEXT: 		      list[0] {{.*}} (struct protocol_t *)
-; MERGE_CATS-NEXT: 			      isa {{.*}}
-; MERGE_CATS-NEXT: 			     name {{.*}} MyTestProtocol
-; MERGE_CATS-NEXT: 			protocols {{.*}}
-; MERGE_CATS-NEXT: 		  instanceMethods {{.*}} (struct method_list_t *)
-; MERGE_CATS-NEXT: 			   entsize 24
-; MERGE_CATS-NEXT: 			     count 1
-; MERGE_CATS-NEXT: 			      name {{.*}} getValue
-; MERGE_CATS-NEXT: 			     types {{.*}} i16 at 0:8
-; MERGE_CATS-NEXT: 			       imp {{.*}}
-; MERGE_CATS-NEXT: 		     classMethods {{.*}} (struct method_list_t *)
-; MERGE_CATS-NEXT: 	  optionalInstanceMethods {{.*}}
-; MERGE_CATS-NEXT: 	     optionalClassMethods {{.*}}
-; MERGE_CATS-NEXT: 	       instanceProperties {{.*}}
+; MERGE_CATS-NEXT:                list[0] {{.*}} (struct protocol_t *)
+; MERGE_CATS-NEXT:                       isa {{.*}}
+; MERGE_CATS-NEXT:                      name {{.*}} MyTestProtocol
+; MERGE_CATS-NEXT:                 protocols {{.*}}
+; MERGE_CATS-NEXT:            instanceMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT:                    entsize 24
+; MERGE_CATS-NEXT:                      count 1
+; MERGE_CATS-NEXT:                       name {{.*}} getValue
+; MERGE_CATS-NEXT:                      types {{.*}} i16 at 0:8
+; MERGE_CATS-NEXT:                        imp {{.*}}
+; MERGE_CATS-NEXT:               classMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT:     optionalInstanceMethods {{.*}}
+; MERGE_CATS-NEXT:        optionalClassMethods {{.*}}
+; MERGE_CATS-NEXT:          instanceProperties {{.*}}
 ; MERGE_CATS-NEXT:                     ivars {{.*}}
 ; MERGE_CATS-NEXT:            weakIvarLayout {{.*}}
 ; MERGE_CATS-NEXT:            baseProperties {{.*}}
@@ -71,20 +71,20 @@
 ; MERGE_CATS-NEXT:               baseMethods {{.*}} (struct method_list_t *)
 ; MERGE_CATS-NEXT:             baseProtocols {{.*}}
 ; MERGE_CATS-NEXT:                       count 1
-; MERGE_CATS-NEXT: 		      list[0] {{.*}} (struct protocol_t *)
-; MERGE_CATS-NEXT: 			      isa {{.*}}
-; MERGE_CATS-NEXT: 			     name {{.*}} MyTestProtocol
-; MERGE_CATS-NEXT: 			protocols {{.*}}
-; MERGE_CATS-NEXT: 		  instanceMethods {{.*}} (struct method_list_t *)
-; MERGE_CATS-NEXT: 			   entsize 24
-; MERGE_CATS-NEXT: 			     count 1
-; MERGE_CATS-NEXT: 			      name {{.*}} getValue
-; MERGE_CATS-NEXT: 			     types {{.*}} i16 at 0:8
-; MERGE_CATS-NEXT: 			       imp {{.*}}
-; MERGE_CATS-NEXT: 		     classMethods {{.*}} (struct method_list_t *)
-; MERGE_CATS-NEXT: 	  optionalInstanceMethods {{.*}}
-; MERGE_CATS-NEXT: 	     optionalClassMethods {{.*}}
-; MERGE_CATS-NEXT: 	       instanceProperties {{.*}}
+; MERGE_CATS-NEXT:                list[0] {{.*}} (struct protocol_t *)
+; MERGE_CATS-NEXT:                       isa {{.*}}
+; MERGE_CATS-NEXT:                      name {{.*}} MyTestProtocol
+; MERGE_CATS-NEXT:                 protocols {{.*}}
+; MERGE_CATS-NEXT:            instanceMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT:                    entsize 24
+; MERGE_CATS-NEXT:                      count 1
+; MERGE_CATS-NEXT:                       name {{.*}} getValue
+; MERGE_CATS-NEXT:                      types {{.*}} i16 at 0:8
+; MERGE_CATS-NEXT:                        imp {{.*}}
+; MERGE_CATS-NEXT:               classMethods {{.*}} (struct method_list_t *)
+; MERGE_CATS-NEXT:     optionalInstanceMethods {{.*}}
+; MERGE_CATS-NEXT:        optionalClassMethods {{.*}}
+; MERGE_CATS-NEXT:          instanceProperties {{.*}}
 ; MERGE_CATS-NEXT:                     ivars {{.*}}
 ; MERGE_CATS-NEXT:            weakIvarLayout {{.*}}
 ; MERGE_CATS-NEXT:            baseProperties {{.*}}
@@ -125,179 +125,180 @@
 ;
 ; # Compile the Objective-C file to assembly
 ; xcrun clang -S -arch arm64 MyClass.m -o MyClass.s
+; ==============================================
 
 
-	.section	__TEXT,__text,regular,pure_instructions
-	.p2align	2                               ; -- Begin function -[MyBaseClass baseInstanceMethod]
+       .section      __TEXT,__text,regular,pure_instructions
+       .p2align      2                               ; -- Begin function -[MyBaseClass baseInstanceMethod]
 "-[MyBaseClass baseInstanceMethod]":    ; @"\01-[MyBaseClass baseInstanceMethod]"
-	.cfi_startproc
+       .cfi_startproc
 ; %bb.0:
-	sub	sp, sp, #16
-	.cfi_def_cfa_offset 16
-	str	x0, [sp, #8]
-	str	x1, [sp]
-	add	sp, sp, #16
-	ret
-	.cfi_endproc
+       sub    sp, sp, #16
+       .cfi_def_cfa_offset 16
+       str    x0, [sp, #8]
+       str    x1, [sp]
+       add    sp, sp, #16
+       ret
+       .cfi_endproc
                                         ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass(MyTestProtocol) getValue]
+       .p2align      2                               ; -- Begin function -[MyBaseClass(MyTestProtocol) getValue]
 "-[MyBaseClass(MyTestProtocol) getValue]": ; @"\01-[MyBaseClass(MyTestProtocol) getValue]"
-	.cfi_startproc
+       .cfi_startproc
 ; %bb.0:
-	sub	sp, sp, #16
-	.cfi_def_cfa_offset 16
-	str	x0, [sp, #8]
-	str	x1, [sp]
-	mov	w0, #48                         ; =0x30
-	add	sp, sp, #16
-	ret
-	.cfi_endproc
+       sub    sp, sp, #16
+       .cfi_def_cfa_offset 16
+       str    x0, [sp, #8]
+       str    x1, [sp]
+       mov    w0, #48                         ; =0x30
+       add    sp, sp, #16
+       ret
+       .cfi_endproc
                                         ; -- End function
-	.section	__DATA,__objc_data
-	.globl	_OBJC_CLASS_$_MyBaseClass       ; @"OBJC_CLASS_$_MyBaseClass"
-	.p2align	3, 0x0
+       .section      __DATA,__objc_data
+       .globl _OBJC_CLASS_$_MyBaseClass       ; @"OBJC_CLASS_$_MyBaseClass"
+       .p2align      3, 0x0
 _OBJC_CLASS_$_MyBaseClass:
-	.quad	_OBJC_METACLASS_$_MyBaseClass
-	.quad	0
-	.quad	__objc_empty_cache
-	.quad	0
-	.quad	__OBJC_CLASS_RO_$_MyBaseClass
-	.globl	_OBJC_METACLASS_$_MyBaseClass   ; @"OBJC_METACLASS_$_MyBaseClass"
-	.p2align	3, 0x0
+       .quad  _OBJC_METACLASS_$_MyBaseClass
+       .quad  0
+       .quad  __objc_empty_cache
+       .quad  0
+       .quad  __OBJC_CLASS_RO_$_MyBaseClass
+       .globl _OBJC_METACLASS_$_MyBaseClass   ; @"OBJC_METACLASS_$_MyBaseClass"
+       .p2align      3, 0x0
 _OBJC_METACLASS_$_MyBaseClass:
-	.quad	_OBJC_METACLASS_$_MyBaseClass
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.quad	__objc_empty_cache
-	.quad	0
-	.quad	__OBJC_METACLASS_RO_$_MyBaseClass
-	.section	__TEXT,__objc_classname,cstring_literals
+       .quad  _OBJC_METACLASS_$_MyBaseClass
+       .quad  _OBJC_CLASS_$_MyBaseClass
+       .quad  __objc_empty_cache
+       .quad  0
+       .quad  __OBJC_METACLASS_RO_$_MyBaseClass
+       .section      __TEXT,__objc_classname,cstring_literals
 l_OBJC_CLASS_NAME_:                     ; @OBJC_CLASS_NAME_
-	.asciz	"MyBaseClass"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_METACLASS_RO_$_MyBaseClass"
+       .asciz "MyBaseClass"
+       .section      __DATA,__objc_const
+       .p2align      3, 0x0                          ; @"_OBJC_METACLASS_RO_$_MyBaseClass"
 __OBJC_METACLASS_RO_$_MyBaseClass:
-	.long	131                             ; 0x83
-	.long	40                              ; 0x28
-	.long	40                              ; 0x28
-	.space	4
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	0
-	.section	__TEXT,__objc_methname,cstring_literals
+       .long  131                             ; 0x83
+       .long  40                              ; 0x28
+       .long  40                              ; 0x28
+       .space 4
+       .quad  0
+       .quad  l_OBJC_CLASS_NAME_
+       .quad  0
+       .quad  0
+       .quad  0
+       .quad  0
+       .quad  0
+       .section      __TEXT,__objc_methname,cstring_literals
 l_OBJC_METH_VAR_NAME_:                  ; @OBJC_METH_VAR_NAME_
-	.asciz	"baseInstanceMethod"
-	.section	__TEXT,__objc_methtype,cstring_literals
+       .asciz "baseInstanceMethod"
+       .section      __TEXT,__objc_methtype,cstring_literals
 l_OBJC_METH_VAR_TYPE_:                  ; @OBJC_METH_VAR_TYPE_
-	.asciz	"v16 at 0:8"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_INSTANCE_METHODS_MyBaseClass"
+       .asciz "v16 at 0:8"
+       .section      __DATA,__objc_const
+       .p2align      3, 0x0                          ; @"_OBJC_$_INSTANCE_METHODS_MyBaseClass"
 __OBJC_$_INSTANCE_METHODS_MyBaseClass:
-	.long	24                              ; 0x18
-	.long	1                               ; 0x1
-	.quad	l_OBJC_METH_VAR_NAME_
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass baseInstanceMethod]"
-	.p2align	3, 0x0                          ; @"_OBJC_CLASS_RO_$_MyBaseClass"
+       .long  24                              ; 0x18
+       .long  1                               ; 0x1
+       .quad  l_OBJC_METH_VAR_NAME_
+       .quad  l_OBJC_METH_VAR_TYPE_
+       .quad  "-[MyBaseClass baseInstanceMethod]"
+       .p2align      3, 0x0                          ; @"_OBJC_CLASS_RO_$_MyBaseClass"
 __OBJC_CLASS_RO_$_MyBaseClass:
-	.long	130                             ; 0x82
-	.long	0                               ; 0x0
-	.long	0                               ; 0x0
-	.space	4
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_
-	.quad	__OBJC_$_INSTANCE_METHODS_MyBaseClass
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	0
-	.section	__TEXT,__objc_classname,cstring_literals
+       .long  130                             ; 0x82
+       .long  0                               ; 0x0
+       .long  0                               ; 0x0
+       .space 4
+       .quad  0
+       .quad  l_OBJC_CLASS_NAME_
+       .quad  __OBJC_$_INSTANCE_METHODS_MyBaseClass
+       .quad  0
+       .quad  0
+       .quad  0
+       .quad  0
+       .section      __TEXT,__objc_classname,cstring_literals
 l_OBJC_CLASS_NAME_.1:                   ; @OBJC_CLASS_NAME_.1
-	.asciz	"MyTestProtocol"
-	.section	__TEXT,__objc_methname,cstring_literals
+       .asciz "MyTestProtocol"
+       .section      __TEXT,__objc_methname,cstring_literals
 l_OBJC_METH_VAR_NAME_.2:                ; @OBJC_METH_VAR_NAME_.2
-	.asciz	"getValue"
-	.section	__TEXT,__objc_methtype,cstring_literals
+       .asciz "getValue"
+       .section      __TEXT,__objc_methtype,cstring_literals
 l_OBJC_METH_VAR_TYPE_.3:                ; @OBJC_METH_VAR_TYPE_.3
-	.asciz	"i16 at 0:8"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol"
+       .asciz "i16 at 0:8"
+       .section      __DATA,__objc_const
+       .p2align      3, 0x0                          ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol"
 __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol:
-	.long	24                              ; 0x18
-	.long	1                               ; 0x1
-	.quad	l_OBJC_METH_VAR_NAME_.2
-	.quad	l_OBJC_METH_VAR_TYPE_.3
-	.quad	"-[MyBaseClass(MyTestProtocol) getValue]"
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol"
+       .long  24                              ; 0x18
+       .long  1                               ; 0x1
+       .quad  l_OBJC_METH_VAR_NAME_.2
+       .quad  l_OBJC_METH_VAR_TYPE_.3
+       .quad  "-[MyBaseClass(MyTestProtocol) getValue]"
+       .p2align      3, 0x0                          ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol"
 __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol:
-	.long	24                              ; 0x18
-	.long	1                               ; 0x1
-	.quad	l_OBJC_METH_VAR_NAME_.2
-	.quad	l_OBJC_METH_VAR_TYPE_.3
-	.quad	0
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol"
+       .long  24                              ; 0x18
+       .long  1                               ; 0x1
+       .quad  l_OBJC_METH_VAR_NAME_.2
+       .quad  l_OBJC_METH_VAR_TYPE_.3
+       .quad  0
+       .p2align      3, 0x0                          ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol"
 __OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol:
-	.quad	l_OBJC_METH_VAR_TYPE_.3
-	.private_extern	__OBJC_PROTOCOL_$_MyTestProtocol ; @"_OBJC_PROTOCOL_$_MyTestProtocol"
-	.section	__DATA,__data
-	.globl	__OBJC_PROTOCOL_$_MyTestProtocol
-	.weak_definition	__OBJC_PROTOCOL_$_MyTestProtocol
-	.p2align	3, 0x0
+       .quad  l_OBJC_METH_VAR_TYPE_.3
+       .private_extern      __OBJC_PROTOCOL_$_MyTestProtocol ; @"_OBJC_PROTOCOL_$_MyTestProtocol"
+       .section      __DATA,__data
+       .globl __OBJC_PROTOCOL_$_MyTestProtocol
+       .weak_definition     __OBJC_PROTOCOL_$_MyTestProtocol
+       .p2align      3, 0x0
 __OBJC_PROTOCOL_$_MyTestProtocol:
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_.1
-	.quad	0
-	.quad	__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	0
-	.long	96                              ; 0x60
-	.long	0                               ; 0x0
-	.quad	__OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol
-	.quad	0
-	.quad	0
-	.private_extern	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol ; @"_OBJC_LABEL_PROTOCOL_$_MyTestProtocol"
-	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
-	.globl	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol
-	.weak_definition	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol
-	.p2align	3, 0x0
+       .quad  0
+       .quad  l_OBJC_CLASS_NAME_.1
+       .quad  0
+       .quad  __OBJC_$_PROTOCOL_INSTANCE_METHODS_MyTestProtocol
+       .quad  0
+       .quad  0
+       .quad  0
+       .quad  0
+       .long  96                              ; 0x60
+       .long  0                               ; 0x0
+       .quad  __OBJC_$_PROTOCOL_METHOD_TYPES_MyTestProtocol
+       .quad  0
+       .quad  0
+       .private_extern      __OBJC_LABEL_PROTOCOL_$_MyTestProtocol ; @"_OBJC_LABEL_PROTOCOL_$_MyTestProtocol"
+       .section      __DATA,__objc_protolist,coalesced,no_dead_strip
+       .globl __OBJC_LABEL_PROTOCOL_$_MyTestProtocol
+       .weak_definition     __OBJC_LABEL_PROTOCOL_$_MyTestProtocol
+       .p2align      3, 0x0
 __OBJC_LABEL_PROTOCOL_$_MyTestProtocol:
-	.quad	__OBJC_PROTOCOL_$_MyTestProtocol
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol"
+       .quad  __OBJC_PROTOCOL_$_MyTestProtocol
+       .section      __DATA,__objc_const
+       .p2align      3, 0x0                          ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol"
 __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol:
-	.quad	1                               ; 0x1
-	.quad	__OBJC_PROTOCOL_$_MyTestProtocol
-	.quad	0
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol"
+       .quad  1                               ; 0x1
+       .quad  __OBJC_PROTOCOL_$_MyTestProtocol
+       .quad  0
+       .p2align      3, 0x0                          ; @"_OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol"
 __OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol:
-	.quad	l_OBJC_CLASS_NAME_.1
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.quad	__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol
-	.quad	0
-	.quad	__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol
-	.quad	0
-	.quad	0
-	.long	64                              ; 0x40
-	.space	4
-	.section	__DATA,__objc_classlist,regular,no_dead_strip
-	.p2align	3, 0x0                          ; @"OBJC_LABEL_CLASS_$"
+       .quad  l_OBJC_CLASS_NAME_.1
+       .quad  _OBJC_CLASS_$_MyBaseClass
+       .quad  __OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_MyTestProtocol
+       .quad  0
+       .quad  __OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_MyTestProtocol
+       .quad  0
+       .quad  0
+       .long  64                              ; 0x40
+       .space 4
+       .section      __DATA,__objc_classlist,regular,no_dead_strip
+       .p2align      3, 0x0                          ; @"OBJC_LABEL_CLASS_$"
 l_OBJC_LABEL_CLASS_$:
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.section	__DATA,__objc_catlist,regular,no_dead_strip
-	.p2align	3, 0x0                          ; @"OBJC_LABEL_CATEGORY_$"
+       .quad  _OBJC_CLASS_$_MyBaseClass
+       .section      __DATA,__objc_catlist,regular,no_dead_strip
+       .p2align      3, 0x0                          ; @"OBJC_LABEL_CATEGORY_$"
 l_OBJC_LABEL_CATEGORY_$:
-	.quad	__OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol
-	.no_dead_strip	__OBJC_PROTOCOL_$_MyTestProtocol
-	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_MyTestProtocol
-	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+       .quad  __OBJC_$_CATEGORY_MyBaseClass_$_MyTestProtocol
+       .no_dead_strip       __OBJC_PROTOCOL_$_MyTestProtocol
+       .no_dead_strip       __OBJC_LABEL_PROTOCOL_$_MyTestProtocol
+       .section      __DATA,__objc_imageinfo,regular,no_dead_strip
 L_OBJC_IMAGE_INFO:
-	.long	0
-	.long	64
+       .long  0
+       .long  64
 
 __objc_empty_cache:
 _$sBOWV:



More information about the llvm-commits mailing list