From f0c8d88e25dbed02605994da227dfa75c1304d4a Mon Sep 17 00:00:00 2001 From: alx32 <103613512+alx32@users.noreply.github.com> Date: Thu, 1 Feb 2024 10:31:27 -0800 Subject: [PATCH] [lld-macho] Make ObjC category checker print the source file name of category (#80221) When printing category conflicts in the ObjC category checker, also print the source file name of the problematic categories. Currently we only print the object file name. This change is mostly useful only for thinLTO builds, where the object file name will be of form 999.arm64.lto.o and thus does not reveal any information about the original source file. --------- Co-authored-by: Alex Borcan --- lld/MachO/ObjC.cpp | 15 ++++++++++-- lld/test/MachO/objc-category-conflicts.s | 30 ++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp index 7e8cec026d2f7c..67254ec53a2145 100644 --- a/lld/MachO/ObjC.cpp +++ b/lld/MachO/ObjC.cpp @@ -237,12 +237,23 @@ void ObjcCategoryChecker::parseMethods(const ConcatInputSection *methodsIsec, StringRef newCatName = getReferentString(*containerIsec->getRelocAt(catLayout.nameOffset)); + auto formatObjAndSrcFileName = [](const InputSection *section) { + lld::macho::InputFile *inputFile = section->getFile(); + std::string result = toString(inputFile); + + auto objFile = dyn_cast_or_null(inputFile); + if (objFile && objFile->compileUnit) + result += " (" + objFile->sourceFile() + ")"; + + return result; + }; + StringRef containerType = mc.kind == MCK_Category ? "category" : "class"; warn("method '" + methPrefix + methodName.val() + "' has conflicting definitions:\n>>> defined in category " + - newCatName + " from " + toString(containerIsec->getFile()) + + newCatName + " from " + formatObjAndSrcFileName(containerIsec) + "\n>>> defined in " + containerType + " " + containerName + " from " + - toString(mc.isec->getFile())); + formatObjAndSrcFileName(mc.isec)); } } diff --git a/lld/test/MachO/objc-category-conflicts.s b/lld/test/MachO/objc-category-conflicts.s index 59a9ed50eb055a..eb4c0adfd9e934 100644 --- a/lld/test/MachO/objc-category-conflicts.s +++ b/lld/test/MachO/objc-category-conflicts.s @@ -3,6 +3,9 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -o %t/cat1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -o %t/cat2.o # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -o %t/klass.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -g -o %t/cat1_w_sym.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -g -o %t/cat2_w_sym.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -g -o %t/klass_w_sym.o # 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 # 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 # 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 @@ -14,6 +17,11 @@ # RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/libklass.dylib %t/cat1.o \ # RUN: %t/cat2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT +# RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/klass_w_sym.o %t/cat1_w_sym.o %t/cat2_w_sym.o -o \ +# RUN: /dev/null 2>&1 | FileCheck %s --check-prefixes=CATCLS_W_SYM,CATCAT_W_SYM +# RUN: %no-fatal-warnings-lld --check-category-conflicts -dylib -lobjc %t/libklass.dylib %t/cat1_w_sym.o \ +# RUN: %t/cat2_w_sym.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT_W_SYM + ## Check that we don't emit spurious warnings around the +load method while ## still emitting the other warnings. Note that we have made separate ## `*-with-load.s` files for ease of comparison with ld64; ld64 will not warn @@ -45,6 +53,24 @@ # CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o # CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o + +# CATCLS_W_SYM: warning: method '+s1' has conflicting definitions: +# CATCLS_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}}) +# CATCLS_W_SYM-NEXT: >>> defined in class Foo from {{.*}}klass_w_sym{{.*}}.o ({{.*}}klass.s{{.*}}) + +# CATCLS_W_SYM: warning: method '-m1' has conflicting definitions: +# CATCLS_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}}) +# CATCLS_W_SYM-NEXT: >>> defined in class Foo from {{.*}}klass_w_sym{{.*}}.o ({{.*}}klass.s{{.*}}) + +# CATCAT_W_SYM: warning: method '+s2' has conflicting definitions: +# CATCAT_W_SYM-NEXT: >>> defined in category Cat2 from {{.*}}cat2_w_sym{{.*}}.o ({{.*}}cat2.s{{.*}}) +# CATCAT_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}}) + +# CATCAT_W_SYM: warning: method '-m2' has conflicting definitions: +# CATCAT_W_SYM-NEXT: >>> defined in category Cat2 from {{.*}}cat2_w_sym{{.*}}.o ({{.*}}cat2.s{{.*}}) +# CATCAT_W_SYM-NEXT: >>> defined in category Cat1 from {{.*}}cat1_w_sym{{.*}}.o ({{.*}}cat1.s{{.*}}) + + #--- cat1.s .include "objc-macros.s" @@ -55,7 +81,7 @@ ## +(void) s1; ## +(void) s2; ## @end -## +## ## @implementation Foo(Cat1) ## -(void) m1 {} ## -(void) m2 {} @@ -114,7 +140,7 @@ __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1: ## -(void) m2; ## +(void) s2; ## @end -## +## ## @implementation Foo(Cat2) ## -(void) m2 {} ## +(void) s2 {}