Revert "[lld-macho] Implement ObjC category merging (-objc_category_merging) (#82928)"

This reverts commit ece2903ce730392e5236d27f1f387fa8067fcb1b, https://github.com/llvm/llvm-project/pull/82928.

https://github.com/llvm/llvm-project/pull/82928

GitOrigin-RevId: 5373daad9492e157c0c1ad496334f5dfd78d7da0
diff --git a/MachO/Driver.cpp b/MachO/Driver.cpp
index 3624892..9edb6b9 100644
--- a/MachO/Driver.cpp
+++ b/MachO/Driver.cpp
@@ -1437,8 +1437,6 @@
     resetOutputSegments();
     resetWriter();
     InputFile::resetIdCount();
-
-    objc::doCleanup();
   };
 
   ctx->e.logName = args::getFilenameWithoutExe(argsArr[0]);
@@ -1981,16 +1979,9 @@
     if (config->deadStrip)
       markLive();
 
-    // Categories are not subject to dead-strip. The __objc_catlist section is
-    // marked as NO_DEAD_STRIP and that propagates into all category data.
     if (args.hasArg(OPT_check_category_conflicts))
       objc::checkCategories();
 
-    // Category merging uses "->live = false" to erase old category data, so
-    // it has to run after dead-stripping (markLive).
-    if (args.hasArg(OPT_objc_category_merging, OPT_no_objc_category_merging))
-      objc::mergeCategories();
-
     // ICF assumes that all literals have been folded already, so we must run
     // foldIdenticalLiterals before foldIdenticalSections.
     foldIdenticalLiterals();
diff --git a/MachO/InputSection.h b/MachO/InputSection.h
index b25f063..becb010 100644
--- a/MachO/InputSection.h
+++ b/MachO/InputSection.h
@@ -93,9 +93,9 @@
   // .subsections_via_symbols, there is typically only one element here.
   llvm::TinyPtrVector<Defined *> symbols;
 
+protected:
   const Section &section;
 
-protected:
   const Defined *getContainingSymbol(uint64_t off) const;
 };
 
diff --git a/MachO/ObjC.cpp b/MachO/ObjC.cpp
index 9b24463..67254ec 100644
--- a/MachO/ObjC.cpp
+++ b/MachO/ObjC.cpp
@@ -7,19 +7,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "ObjC.h"
-#include "ConcatOutputSection.h"
 #include "InputFiles.h"
 #include "InputSection.h"
 #include "Layout.h"
 #include "OutputSegment.h"
-#include "SyntheticSections.h"
 #include "Target.h"
 
 #include "lld/Common/ErrorHandler.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/Support/TimeProfiler.h"
 
 using namespace llvm;
 using namespace llvm::MachO;
@@ -81,8 +78,7 @@
   DO(Ptr, classMethods)                                                        \
   DO(Ptr, protocols)                                                           \
   DO(Ptr, instanceProps)                                                       \
-  DO(Ptr, classProps)                                                          \
-  DO(uint32_t, size)
+  DO(Ptr, classProps)
 
 CREATE_LAYOUT_CLASS(Category, FOR_EACH_CATEGORY_FIELD);
 
@@ -116,19 +112,13 @@
 #undef FOR_EACH_RO_CLASS_FIELD
 
 #define FOR_EACH_LIST_HEADER(DO)                                               \
-  DO(uint32_t, structSize)                                                     \
-  DO(uint32_t, structCount)
+  DO(uint32_t, size)                                                           \
+  DO(uint32_t, count)
 
 CREATE_LAYOUT_CLASS(ListHeader, FOR_EACH_LIST_HEADER);
 
 #undef FOR_EACH_LIST_HEADER
 
-#define FOR_EACH_PROTOCOL_LIST_HEADER(DO) DO(Ptr, protocolCount)
-
-CREATE_LAYOUT_CLASS(ProtocolListHeader, FOR_EACH_PROTOCOL_LIST_HEADER);
-
-#undef FOR_EACH_PROTOCOL_LIST_HEADER
-
 #define FOR_EACH_METHOD(DO)                                                    \
   DO(Ptr, name)                                                                \
   DO(Ptr, type)                                                                \
@@ -321,8 +311,6 @@
 }
 
 void objc::checkCategories() {
-  TimeTraceScope timeScope("ObjcCategoryChecker");
-
   ObjcCategoryChecker checker;
   for (const InputSection *isec : inputSections) {
     if (isec->getName() == section_names::objcCatList)
@@ -332,905 +320,3 @@
       }
   }
 }
-
-namespace {
-
-class ObjcCategoryMerger {
-  // Information about an input category
-  struct InfoInputCategory {
-    ConcatInputSection *catListIsec;
-    ConcatInputSection *catBodyIsec;
-    uint32_t offCatListIsec = 0;
-
-    bool wasMerged = false;
-  };
-
-  // To write new (merged) categories or classes, we will try make limited
-  // assumptions about the alignment and the sections the various class/category
-  // info are stored in and . So we'll just reuse the same sections and
-  // alignment as already used in existing (input) categories. To do this we
-  // have InfoCategoryWriter which contains the various sections that the
-  // generated categories will be written to.
-  template <typename T> struct InfoWriteSection {
-    bool valid = false; // Data has been successfully collected from input
-    uint32_t align = 0;
-    Section *inputSection;
-    Reloc relocTemplate;
-    T *outputSection;
-  };
-
-  struct InfoCategoryWriter {
-    InfoWriteSection<ConcatOutputSection> catListInfo;
-    InfoWriteSection<ConcatOutputSection> catBodyInfo;
-    InfoWriteSection<CStringSection> catNameInfo;
-    InfoWriteSection<ConcatOutputSection> catPtrListInfo;
-  };
-
-  // Information about a pointer list in the original categories (method lists,
-  // protocol lists, etc)
-  struct PointerListInfo {
-    PointerListInfo(const char *_categoryPrefix, uint32_t _categoryOffset,
-                    uint32_t _pointersPerStruct)
-        : categoryPrefix(_categoryPrefix), categoryOffset(_categoryOffset),
-          pointersPerStruct(_pointersPerStruct) {}
-    const char *categoryPrefix;
-    uint32_t categoryOffset = 0;
-
-    uint32_t pointersPerStruct = 0;
-
-    uint32_t structSize = 0;
-    uint32_t structCount = 0;
-
-    std::vector<Symbol *> allPtrs;
-  };
-
-  // Full information about all the categories that extend a class. This will
-  // include all the additional methods, protocols, and properties that are
-  // contained in all the categories that extend a particular class.
-  struct ClassExtensionInfo {
-    ClassExtensionInfo(CategoryLayout &_catLayout) : catLayout(_catLayout){};
-
-    // Merged names of containers. Ex: base|firstCategory|secondCategory|...
-    std::string mergedContainerName;
-    std::string baseClassName;
-    Symbol *baseClass = nullptr;
-    CategoryLayout &catLayout;
-
-    // In case we generate new data, mark the new data as belonging to this file
-    ObjFile *objFileForMergeData = nullptr;
-
-    PointerListInfo instanceMethods = {
-        objc::symbol_names::categoryInstanceMethods,
-        /*_categoryOffset=*/catLayout.instanceMethodsOffset,
-        /*pointersPerStruct=*/3};
-    PointerListInfo classMethods = {
-        objc::symbol_names::categoryClassMethods,
-        /*_categoryOffset=*/catLayout.classMethodsOffset,
-        /*pointersPerStruct=*/3};
-    PointerListInfo protocols = {objc::symbol_names::categoryProtocols,
-                                 /*_categoryOffset=*/catLayout.protocolsOffset,
-                                 /*pointersPerStruct=*/0};
-    PointerListInfo instanceProps = {
-        objc::symbol_names::listProprieties,
-        /*_categoryOffset=*/catLayout.instancePropsOffset,
-        /*pointersPerStruct=*/2};
-    PointerListInfo classProps = {
-        objc::symbol_names::klassPropList,
-        /*_categoryOffset=*/catLayout.classPropsOffset,
-        /*pointersPerStruct=*/2};
-  };
-
-public:
-  ObjcCategoryMerger(std::vector<ConcatInputSection *> &_allInputSections);
-  void doMerge();
-  static void doCleanup();
-
-private:
-  void collectAndValidateCategoriesData();
-  void
-  mergeCategoriesIntoSingleCategory(std::vector<InfoInputCategory> &categories);
-
-  void eraseISec(ConcatInputSection *isec);
-  void eraseMergedCategories();
-
-  void generateCatListForNonErasedCategories(
-      std::map<ConcatInputSection *, std::set<uint64_t>>
-          catListToErasedOffsets);
-  template <typename T>
-  void collectSectionWriteInfoFromIsec(const InputSection *isec,
-                                       InfoWriteSection<T> &catWriteInfo);
-  void collectCategoryWriterInfoFromCategory(const InfoInputCategory &catInfo);
-  void parseCatInfoToExtInfo(const InfoInputCategory &catInfo,
-                             ClassExtensionInfo &extInfo);
-
-  void parseProtocolListInfo(const ConcatInputSection *isec, uint32_t secOffset,
-                             PointerListInfo &ptrList);
-
-  void parsePointerListInfo(const ConcatInputSection *isec, uint32_t secOffset,
-                            PointerListInfo &ptrList);
-
-  void emitAndLinkPointerList(Defined *parentSym, uint32_t linkAtOffset,
-                              const ClassExtensionInfo &extInfo,
-                              const PointerListInfo &ptrList);
-
-  void emitAndLinkProtocolList(Defined *parentSym, uint32_t linkAtOffset,
-                               const ClassExtensionInfo &extInfo,
-                               const PointerListInfo &ptrList);
-
-  Defined *emitCategory(const ClassExtensionInfo &extInfo);
-  Defined *emitCatListEntrySec(const std::string &forCateogryName,
-                               const std::string &forBaseClassName,
-                               ObjFile *objFile);
-  Defined *emitCategoryBody(const std::string &name, const Defined *nameSym,
-                            const Symbol *baseClassSym,
-                            const std::string &baseClassName, ObjFile *objFile);
-  Defined *emitCategoryName(const std::string &name, ObjFile *objFile);
-  void createSymbolReference(Defined *refFrom, const Symbol *refTo,
-                             uint32_t offset, const Reloc &relocTemplate);
-  Symbol *tryGetSymbolAtIsecOffset(const ConcatInputSection *isec,
-                                   uint32_t offset);
-  Defined *tryGetDefinedAtIsecOffset(const ConcatInputSection *isec,
-                                     uint32_t offset);
-  void tryEraseDefinedAtIsecOffset(const ConcatInputSection *isec,
-                                   uint32_t offset);
-
-  // Allocate a null-terminated StringRef backed by generatedSectionData
-  StringRef newStringData(const char *str);
-  // Allocate section data, backed by generatedSectionData
-  SmallVector<uint8_t> &newSectionData(uint32_t size);
-
-  CategoryLayout catLayout;
-  ClassLayout classLayout;
-  ROClassLayout roClassLayout;
-  ListHeaderLayout listHeaderLayout;
-  MethodLayout methodLayout;
-  ProtocolListHeaderLayout protocolListHeaderLayout;
-
-  InfoCategoryWriter infoCategoryWriter;
-  std::vector<ConcatInputSection *> &allInputSections;
-  // Map of base class Symbol to list of InfoInputCategory's for it
-  DenseMap<const Symbol *, std::vector<InfoInputCategory>> categoryMap;
-
-  // Normally, the binary data comes from the input files, but since we're
-  // generating binary data ourselves, we use the below array to store it in.
-  // Need this to be 'static' so the data survives past the ObjcCategoryMerger
-  // object, as the data will be read by the Writer when the final binary is
-  // generated.
-  static SmallVector<SmallVector<uint8_t>> generatedSectionData;
-};
-
-SmallVector<SmallVector<uint8_t>> ObjcCategoryMerger::generatedSectionData;
-
-ObjcCategoryMerger::ObjcCategoryMerger(
-    std::vector<ConcatInputSection *> &_allInputSections)
-    : catLayout(target->wordSize), classLayout(target->wordSize),
-      roClassLayout(target->wordSize), listHeaderLayout(target->wordSize),
-      methodLayout(target->wordSize),
-      protocolListHeaderLayout(target->wordSize),
-      allInputSections(_allInputSections) {}
-
-// This is a template so that it can be used both for CStringSection and
-// ConcatOutputSection
-template <typename T>
-void ObjcCategoryMerger::collectSectionWriteInfoFromIsec(
-    const InputSection *isec, InfoWriteSection<T> &catWriteInfo) {
-
-  catWriteInfo.inputSection = const_cast<Section *>(&isec->section);
-  catWriteInfo.align = isec->align;
-  catWriteInfo.outputSection = dyn_cast_or_null<T>(isec->parent);
-
-  assert(catWriteInfo.outputSection &&
-         "outputSection may not be null in collectSectionWriteInfoFromIsec.");
-
-  if (isec->relocs.size())
-    catWriteInfo.relocTemplate = isec->relocs[0];
-
-  catWriteInfo.valid = true;
-}
-
-Symbol *
-ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const ConcatInputSection *isec,
-                                             uint32_t offset) {
-  const Reloc *reloc = isec->getRelocAt(offset);
-
-  if (!reloc)
-    return nullptr;
-
-  return reloc->referent.get<Symbol *>();
-}
-
-Defined *
-ObjcCategoryMerger::tryGetDefinedAtIsecOffset(const ConcatInputSection *isec,
-                                              uint32_t offset) {
-  Symbol *sym = tryGetSymbolAtIsecOffset(isec, offset);
-  return dyn_cast_or_null<Defined>(sym);
-}
-
-// Given an ConcatInputSection or CStringInputSection and an offset, if there is
-// a symbol(Defined) at that offset, then erase the symbol (mark it not live)
-void ObjcCategoryMerger::tryEraseDefinedAtIsecOffset(
-    const ConcatInputSection *isec, uint32_t offset) {
-  const Reloc *reloc = isec->getRelocAt(offset);
-
-  if (!reloc)
-    return;
-
-  Defined *sym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>());
-  if (!sym)
-    return;
-
-  if (auto *cisec = dyn_cast_or_null<ConcatInputSection>(sym->isec))
-    eraseISec(cisec);
-  else if (auto *csisec = dyn_cast_or_null<CStringInputSection>(sym->isec)) {
-    uint32_t totalOffset = sym->value + reloc->addend;
-    StringPiece &piece = csisec->getStringPiece(totalOffset);
-    piece.live = false;
-  } else {
-    llvm_unreachable("erased symbol has to be Defined or CStringInputSection");
-  }
-}
-
-void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory(
-    const InfoInputCategory &catInfo) {
-
-  if (!infoCategoryWriter.catListInfo.valid)
-    collectSectionWriteInfoFromIsec<ConcatOutputSection>(
-        catInfo.catListIsec, infoCategoryWriter.catListInfo);
-  if (!infoCategoryWriter.catBodyInfo.valid)
-    collectSectionWriteInfoFromIsec<ConcatOutputSection>(
-        catInfo.catBodyIsec, infoCategoryWriter.catBodyInfo);
-
-  if (!infoCategoryWriter.catNameInfo.valid) {
-    lld::macho::Defined *catNameSym =
-        tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
-    assert(catNameSym && "Category does not have a valid name Symbol");
-
-    collectSectionWriteInfoFromIsec<CStringSection>(
-        catNameSym->isec, infoCategoryWriter.catNameInfo);
-  }
-
-  // Collect writer info from all the category lists (we're assuming they all
-  // would provide the same info)
-  if (!infoCategoryWriter.catPtrListInfo.valid) {
-    for (uint32_t off = catLayout.instanceMethodsOffset;
-         off <= catLayout.classPropsOffset; off += target->wordSize) {
-      if (Defined *ptrList =
-              tryGetDefinedAtIsecOffset(catInfo.catBodyIsec, off)) {
-        collectSectionWriteInfoFromIsec<ConcatOutputSection>(
-            ptrList->isec, infoCategoryWriter.catPtrListInfo);
-        // we've successfully collected data, so we can break
-        break;
-      }
-    }
-  }
-}
-
-// Parse a protocol list that might be linked to ConcatInputSection at a given
-// offset. The format of the protocol list is different than other lists (prop
-// lists, method lists) so we need to parse it differently
-void ObjcCategoryMerger::parseProtocolListInfo(const ConcatInputSection *isec,
-                                               uint32_t secOffset,
-                                               PointerListInfo &ptrList) {
-  if (!isec || (secOffset + target->wordSize > isec->data.size()))
-    assert("Tried to read pointer list beyond protocol section end");
-
-  const Reloc *reloc = isec->getRelocAt(secOffset);
-  if (!reloc)
-    return;
-
-  auto *ptrListSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>());
-  assert(ptrListSym && "Protocol list reloc does not have a valid Defined");
-
-  // Theoretically protocol count can be either 32b or 64b, depending on
-  // platform pointer size, but to simplify implementation we always just read
-  // the lower 32b which should be good enough.
-  uint32_t protocolCount = *reinterpret_cast<const uint32_t *>(
-      ptrListSym->isec->data.data() + listHeaderLayout.structSizeOffset);
-
-  ptrList.structCount += protocolCount;
-  ptrList.structSize = target->wordSize;
-
-  uint32_t expectedListSize =
-      (protocolCount * target->wordSize) +
-      /*header(count)*/ protocolListHeaderLayout.totalSize +
-      /*extra null value*/ target->wordSize;
-  assert(expectedListSize == ptrListSym->isec->data.size() &&
-         "Protocol list does not match expected size");
-
-  uint32_t off = protocolListHeaderLayout.totalSize;
-  for (uint32_t inx = 0; inx < protocolCount; ++inx) {
-    const Reloc *reloc = ptrListSym->isec->getRelocAt(off);
-    assert(reloc && "No reloc found at protocol list offset");
-
-    auto *listSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>());
-    assert(listSym && "Protocol list reloc does not have a valid Defined");
-
-    ptrList.allPtrs.push_back(listSym);
-    off += target->wordSize;
-  }
-  assert((ptrListSym->isec->getRelocAt(off) == nullptr) &&
-         "expected null terminating protocol");
-  assert(off + /*extra null value*/ target->wordSize == expectedListSize &&
-         "Protocol list end offset does not match expected size");
-}
-
-// Parse a pointer list that might be linked to ConcatInputSection at a given
-// offset. This can be used for instance methods, class methods, instance props
-// and class props since they have the same format.
-void ObjcCategoryMerger::parsePointerListInfo(const ConcatInputSection *isec,
-                                              uint32_t secOffset,
-                                              PointerListInfo &ptrList) {
-  assert(ptrList.pointersPerStruct == 2 || ptrList.pointersPerStruct == 3);
-  assert(isec && "Trying to parse pointer list from null isec");
-  assert(secOffset + target->wordSize <= isec->data.size() &&
-         "Trying to read pointer list beyond section end");
-
-  const Reloc *reloc = isec->getRelocAt(secOffset);
-  if (!reloc)
-    return;
-
-  auto *ptrListSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>());
-  assert(ptrListSym && "Reloc does not have a valid Defined");
-
-  uint32_t thisStructSize = *reinterpret_cast<const uint32_t *>(
-      ptrListSym->isec->data.data() + listHeaderLayout.structSizeOffset);
-  uint32_t thisStructCount = *reinterpret_cast<const uint32_t *>(
-      ptrListSym->isec->data.data() + listHeaderLayout.structCountOffset);
-  assert(thisStructSize == ptrList.pointersPerStruct * target->wordSize);
-
-  assert(!ptrList.structSize || (thisStructSize == ptrList.structSize));
-
-  ptrList.structCount += thisStructCount;
-  ptrList.structSize = thisStructSize;
-
-  uint32_t expectedListSize =
-      listHeaderLayout.totalSize + (thisStructSize * thisStructCount);
-  assert(expectedListSize == ptrListSym->isec->data.size() &&
-         "Pointer list does not match expected size");
-
-  for (uint32_t off = listHeaderLayout.totalSize; off < expectedListSize;
-       off += target->wordSize) {
-    const Reloc *reloc = ptrListSym->isec->getRelocAt(off);
-    assert(reloc && "No reloc found at pointer list offset");
-
-    auto *listSym = dyn_cast_or_null<Defined>(reloc->referent.get<Symbol *>());
-    assert(listSym && "Reloc does not have a valid Defined");
-
-    ptrList.allPtrs.push_back(listSym);
-  }
-}
-
-// Here we parse all the information of an input category (catInfo) and
-// append the parsed info into the structure which will contain all the
-// information about how a class is extended (extInfo)
-void ObjcCategoryMerger::parseCatInfoToExtInfo(const InfoInputCategory &catInfo,
-                                               ClassExtensionInfo &extInfo) {
-  const Reloc *catNameReloc =
-      catInfo.catBodyIsec->getRelocAt(catLayout.nameOffset);
-
-  // Parse name
-  assert(catNameReloc && "Category does not have a reloc at 'nameOffset'");
-
-  // is this the first category we are parsing?
-  if (extInfo.mergedContainerName.empty())
-    extInfo.objFileForMergeData =
-        dyn_cast_or_null<ObjFile>(catInfo.catBodyIsec->getFile());
-  else
-    extInfo.mergedContainerName += "|";
-
-  assert(extInfo.objFileForMergeData &&
-         "Expected to already have valid objextInfo.objFileForMergeData");
-
-  StringRef catName = getReferentString(*catNameReloc);
-  extInfo.mergedContainerName += catName.str();
-
-  // Parse base class
-  if (!extInfo.baseClass) {
-    Symbol *classSym =
-        tryGetSymbolAtIsecOffset(catInfo.catBodyIsec, catLayout.klassOffset);
-    assert(extInfo.baseClassName.empty());
-    extInfo.baseClass = classSym;
-    llvm::StringRef classPrefix(objc::symbol_names::klass);
-    assert(classSym->getName().starts_with(classPrefix) &&
-           "Base class symbol does not start with expected prefix");
-    extInfo.baseClassName = classSym->getName().substr(classPrefix.size());
-  } else {
-    assert((extInfo.baseClass ==
-            tryGetSymbolAtIsecOffset(catInfo.catBodyIsec,
-                                     catLayout.klassOffset)) &&
-           "Trying to parse category info into container with different base "
-           "class");
-  }
-
-  parsePointerListInfo(catInfo.catBodyIsec, catLayout.instanceMethodsOffset,
-                       extInfo.instanceMethods);
-
-  parsePointerListInfo(catInfo.catBodyIsec, catLayout.classMethodsOffset,
-                       extInfo.classMethods);
-
-  parseProtocolListInfo(catInfo.catBodyIsec, catLayout.protocolsOffset,
-                        extInfo.protocols);
-
-  parsePointerListInfo(catInfo.catBodyIsec, catLayout.instancePropsOffset,
-                       extInfo.instanceProps);
-
-  parsePointerListInfo(catInfo.catBodyIsec, catLayout.classPropsOffset,
-                       extInfo.classProps);
-}
-
-// Generate a protocol list (including header) and link it into the parent at
-// the specified offset.
-void ObjcCategoryMerger::emitAndLinkProtocolList(
-    Defined *parentSym, uint32_t linkAtOffset,
-    const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) {
-  if (ptrList.allPtrs.empty())
-    return;
-
-  assert(ptrList.allPtrs.size() == ptrList.structCount);
-
-  uint32_t bodySize = (ptrList.structCount * target->wordSize) +
-                      /*header(count)*/ protocolListHeaderLayout.totalSize +
-                      /*extra null value*/ target->wordSize;
-  llvm::ArrayRef<uint8_t> bodyData = newSectionData(bodySize);
-
-  // This theoretically can be either 32b or 64b, but writing just the first 32b
-  // is good enough
-  const uint32_t *ptrProtoCount = reinterpret_cast<const uint32_t *>(
-      bodyData.data() + protocolListHeaderLayout.protocolCountOffset);
-
-  *const_cast<uint32_t *>(ptrProtoCount) = ptrList.allPtrs.size();
-
-  ConcatInputSection *listSec = make<ConcatInputSection>(
-      *infoCategoryWriter.catPtrListInfo.inputSection, bodyData,
-      infoCategoryWriter.catPtrListInfo.align);
-  listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
-  listSec->live = true;
-  allInputSections.push_back(listSec);
-
-  listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
-
-  std::string symName = ptrList.categoryPrefix;
-  symName += extInfo.baseClassName + "_$_(" + extInfo.mergedContainerName + ")";
-
-  Defined *ptrListSym = make<Defined>(
-      newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(),
-      listSec, /*value=*/0, bodyData.size(), /*isWeakDef=*/false,
-      /*isExternal=*/false, /*isPrivateExtern=*/false, /*includeInSymtab=*/true,
-      /*isReferencedDynamically=*/false, /*noDeadStrip=*/false,
-      /*isWeakDefCanBeHidden=*/false);
-
-  ptrListSym->used = true;
-  parentSym->getObjectFile()->symbols.push_back(ptrListSym);
-
-  createSymbolReference(parentSym, ptrListSym, linkAtOffset,
-                        infoCategoryWriter.catBodyInfo.relocTemplate);
-
-  uint32_t offset = protocolListHeaderLayout.totalSize;
-  for (Symbol *symbol : ptrList.allPtrs) {
-    createSymbolReference(ptrListSym, symbol, offset,
-                          infoCategoryWriter.catPtrListInfo.relocTemplate);
-    offset += target->wordSize;
-  }
-}
-
-// Generate a pointer list (including header) and link it into the parent at the
-// specified offset. This is used for instance and class methods and
-// proprieties.
-void ObjcCategoryMerger::emitAndLinkPointerList(
-    Defined *parentSym, uint32_t linkAtOffset,
-    const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) {
-  if (ptrList.allPtrs.empty())
-    return;
-
-  assert(ptrList.allPtrs.size() * target->wordSize ==
-         ptrList.structCount * ptrList.structSize);
-
-  // Generate body
-  uint32_t bodySize =
-      listHeaderLayout.totalSize + (ptrList.structSize * ptrList.structCount);
-  llvm::ArrayRef<uint8_t> bodyData = newSectionData(bodySize);
-
-  const uint32_t *ptrStructSize = reinterpret_cast<const uint32_t *>(
-      bodyData.data() + listHeaderLayout.structSizeOffset);
-  const uint32_t *ptrStructCount = reinterpret_cast<const uint32_t *>(
-      bodyData.data() + listHeaderLayout.structCountOffset);
-
-  *const_cast<uint32_t *>(ptrStructSize) = ptrList.structSize;
-  *const_cast<uint32_t *>(ptrStructCount) = ptrList.structCount;
-
-  ConcatInputSection *listSec = make<ConcatInputSection>(
-      *infoCategoryWriter.catPtrListInfo.inputSection, bodyData,
-      infoCategoryWriter.catPtrListInfo.align);
-  listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
-  listSec->live = true;
-  allInputSections.push_back(listSec);
-
-  listSec->parent = infoCategoryWriter.catPtrListInfo.outputSection;
-
-  std::string symName = ptrList.categoryPrefix;
-  symName += extInfo.baseClassName + "_$_" + extInfo.mergedContainerName;
-
-  Defined *ptrListSym = make<Defined>(
-      newStringData(symName.c_str()), /*file=*/parentSym->getObjectFile(),
-      listSec, /*value=*/0, bodyData.size(), /*isWeakDef=*/false,
-      /*isExternal=*/false, /*isPrivateExtern=*/false, /*includeInSymtab=*/true,
-      /*isReferencedDynamically=*/false, /*noDeadStrip=*/false,
-      /*isWeakDefCanBeHidden=*/false);
-
-  ptrListSym->used = true;
-  parentSym->getObjectFile()->symbols.push_back(ptrListSym);
-
-  createSymbolReference(parentSym, ptrListSym, linkAtOffset,
-                        infoCategoryWriter.catBodyInfo.relocTemplate);
-
-  uint32_t offset = listHeaderLayout.totalSize;
-  for (Symbol *symbol : ptrList.allPtrs) {
-    createSymbolReference(ptrListSym, symbol, offset,
-                          infoCategoryWriter.catPtrListInfo.relocTemplate);
-    offset += target->wordSize;
-  }
-}
-
-// This method creates an __objc_catlist ConcatInputSection with a single slot
-Defined *
-ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCateogryName,
-                                        const std::string &forBaseClassName,
-                                        ObjFile *objFile) {
-  uint32_t sectionSize = target->wordSize;
-  llvm::ArrayRef<uint8_t> bodyData = newSectionData(sectionSize);
-
-  ConcatInputSection *newCatList =
-      make<ConcatInputSection>(*infoCategoryWriter.catListInfo.inputSection,
-                               bodyData, infoCategoryWriter.catListInfo.align);
-  newCatList->parent = infoCategoryWriter.catListInfo.outputSection;
-  newCatList->live = true;
-  allInputSections.push_back(newCatList);
-
-  newCatList->parent = infoCategoryWriter.catListInfo.outputSection;
-
-  std::string catSymName = "<__objc_catlist slot for merged category ";
-  catSymName += forBaseClassName + "(" + forCateogryName + ")>";
-
-  Defined *catListSym = make<Defined>(
-      newStringData(catSymName.c_str()), /*file=*/objFile, newCatList,
-      /*value=*/0, bodyData.size(), /*isWeakDef=*/false, /*isExternal=*/false,
-      /*isPrivateExtern=*/false, /*includeInSymtab=*/false,
-      /*isReferencedDynamically=*/false, /*noDeadStrip=*/false,
-      /*isWeakDefCanBeHidden=*/false);
-
-  catListSym->used = true;
-  objFile->symbols.push_back(catListSym);
-  return catListSym;
-}
-
-// Here we generate the main category body and link the name and base class into
-// it. We don't link any other info yet like the protocol and class/instance
-// methods/props.
-Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
-                                              const Defined *nameSym,
-                                              const Symbol *baseClassSym,
-                                              const std::string &baseClassName,
-                                              ObjFile *objFile) {
-  llvm::ArrayRef<uint8_t> bodyData = newSectionData(catLayout.totalSize);
-
-  uint32_t *ptrSize = (uint32_t *)(const_cast<uint8_t *>(bodyData.data()) +
-                                   catLayout.sizeOffset);
-  *ptrSize = catLayout.totalSize;
-
-  ConcatInputSection *newBodySec =
-      make<ConcatInputSection>(*infoCategoryWriter.catBodyInfo.inputSection,
-                               bodyData, infoCategoryWriter.catBodyInfo.align);
-  newBodySec->parent = infoCategoryWriter.catBodyInfo.outputSection;
-  newBodySec->live = true;
-  allInputSections.push_back(newBodySec);
-
-  std::string symName =
-      objc::symbol_names::category + baseClassName + "_$_(" + name + ")";
-  Defined *catBodySym = make<Defined>(
-      newStringData(symName.c_str()), /*file=*/objFile, newBodySec,
-      /*value=*/0, bodyData.size(), /*isWeakDef=*/false, /*isExternal=*/false,
-      /*isPrivateExtern=*/false, /*includeInSymtab=*/true,
-      /*isReferencedDynamically=*/false, /*noDeadStrip=*/false,
-      /*isWeakDefCanBeHidden=*/false);
-
-  catBodySym->used = true;
-  objFile->symbols.push_back(catBodySym);
-
-  createSymbolReference(catBodySym, nameSym, catLayout.nameOffset,
-                        infoCategoryWriter.catBodyInfo.relocTemplate);
-
-  // Create a reloc to the base class (either external or internal)
-  createSymbolReference(catBodySym, baseClassSym, catLayout.klassOffset,
-                        infoCategoryWriter.catBodyInfo.relocTemplate);
-
-  return catBodySym;
-}
-
-// This writes the new category name (for the merged category) into the binary
-// and returns the sybmol for it.
-Defined *ObjcCategoryMerger::emitCategoryName(const std::string &name,
-                                              ObjFile *objFile) {
-  StringRef nameStrData = newStringData(name.c_str());
-  // We use +1 below to include the null terminator
-  llvm::ArrayRef<uint8_t> nameData(
-      reinterpret_cast<const uint8_t *>(nameStrData.data()),
-      nameStrData.size() + 1);
-
-  auto *parentSection = infoCategoryWriter.catNameInfo.inputSection;
-  CStringInputSection *newStringSec = make<CStringInputSection>(
-      *infoCategoryWriter.catNameInfo.inputSection, nameData,
-      infoCategoryWriter.catNameInfo.align, /*dedupLiterals=*/true);
-
-  parentSection->subsections.push_back({0, newStringSec});
-
-  newStringSec->splitIntoPieces();
-  newStringSec->pieces[0].live = true;
-  newStringSec->parent = infoCategoryWriter.catNameInfo.outputSection;
-  in.cStringSection->addInput(newStringSec);
-  assert(newStringSec->pieces.size() == 1);
-
-  Defined *catNameSym = make<Defined>(
-      "<merged category name>", /*file=*/objFile, newStringSec,
-      /*value=*/0, nameData.size(),
-      /*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/false,
-      /*includeInSymtab=*/false, /*isReferencedDynamically=*/false,
-      /*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false);
-
-  catNameSym->used = true;
-  objFile->symbols.push_back(catNameSym);
-  return catNameSym;
-}
-
-// This method fully creates a new category from the given ClassExtensionInfo.
-// It creates the category name, body and method/protocol/prop lists and links
-// them all together. Then it creates a new __objc_catlist entry and adds the
-// category to it. Calling this method will fully generate a category which will
-// be available in the final binary.
-Defined *ObjcCategoryMerger::emitCategory(const ClassExtensionInfo &extInfo) {
-  Defined *catNameSym = emitCategoryName(extInfo.mergedContainerName,
-                                         extInfo.objFileForMergeData);
-
-  Defined *catBodySym = emitCategoryBody(
-      extInfo.mergedContainerName, catNameSym, extInfo.baseClass,
-      extInfo.baseClassName, extInfo.objFileForMergeData);
-
-  Defined *catListSym =
-      emitCatListEntrySec(extInfo.mergedContainerName, extInfo.baseClassName,
-                          extInfo.objFileForMergeData);
-
-  // Add the single category body to the category list at the offset 0.
-  createSymbolReference(catListSym, catBodySym, /*offset=*/0,
-                        infoCategoryWriter.catListInfo.relocTemplate);
-
-  emitAndLinkPointerList(catBodySym, catLayout.instanceMethodsOffset, extInfo,
-                         extInfo.instanceMethods);
-
-  emitAndLinkPointerList(catBodySym, catLayout.classMethodsOffset, extInfo,
-                         extInfo.classMethods);
-
-  emitAndLinkProtocolList(catBodySym, catLayout.protocolsOffset, extInfo,
-                          extInfo.protocols);
-
-  emitAndLinkPointerList(catBodySym, catLayout.instancePropsOffset, extInfo,
-                         extInfo.instanceProps);
-
-  emitAndLinkPointerList(catBodySym, catLayout.classPropsOffset, extInfo,
-                         extInfo.classProps);
-
-  return catBodySym;
-}
-
-// This method merges all the categories (sharing a base class) into a single
-// category.
-void ObjcCategoryMerger::mergeCategoriesIntoSingleCategory(
-    std::vector<InfoInputCategory> &categories) {
-  assert(categories.size() > 1 && "Expected at least 2 categories");
-
-  ClassExtensionInfo extInfo(catLayout);
-
-  for (auto &catInfo : categories)
-    parseCatInfoToExtInfo(catInfo, extInfo);
-
-  Defined *newCatDef = emitCategory(extInfo);
-  assert(newCatDef && "Failed to create a new category");
-
-  for (auto &catInfo : categories)
-    catInfo.wasMerged = true;
-}
-
-void ObjcCategoryMerger::createSymbolReference(Defined *refFrom,
-                                               const Symbol *refTo,
-                                               uint32_t offset,
-                                               const Reloc &relocTemplate) {
-  Reloc r = relocTemplate;
-  r.offset = offset;
-  r.addend = 0;
-  r.referent = const_cast<Symbol *>(refTo);
-  refFrom->isec->relocs.push_back(r);
-}
-
-void ObjcCategoryMerger::collectAndValidateCategoriesData() {
-  for (InputSection *sec : allInputSections) {
-    if (sec->getName() != section_names::objcCatList)
-      continue;
-    ConcatInputSection *catListCisec = dyn_cast<ConcatInputSection>(sec);
-    assert(catListCisec &&
-           "__objc_catList InputSection is not a ConcatInputSection");
-
-    for (uint32_t off = 0; off < catListCisec->getSize();
-         off += target->wordSize) {
-      Defined *categorySym = tryGetDefinedAtIsecOffset(catListCisec, off);
-      assert(categorySym &&
-             "Failed to get a valid cateogry at __objc_catlit offset");
-
-      // We only support ObjC categories (no swift + @objc)
-      // TODO: Support swift + @objc categories also
-      if (!categorySym->getName().starts_with(objc::symbol_names::category))
-        continue;
-
-      auto *catBodyIsec = dyn_cast<ConcatInputSection>(categorySym->isec);
-      assert(catBodyIsec &&
-             "Category data section is not an ConcatInputSection");
-
-      // Check that the category has a reloc at 'klassOffset' (which is
-      // a pointer to the class symbol)
-
-      Symbol *classSym =
-          tryGetSymbolAtIsecOffset(catBodyIsec, catLayout.klassOffset);
-      assert(classSym && "Category does not have a valid base class");
-
-      InfoInputCategory catInputInfo{catListCisec, catBodyIsec, off};
-      categoryMap[classSym].push_back(catInputInfo);
-
-      collectCategoryWriterInfoFromCategory(catInputInfo);
-    }
-  }
-}
-
-// In the input we have multiple __objc_catlist InputSection, each of which may
-// contain links to multiple categories. Of these categories, we will merge (and
-// erase) only some. There will be some categories that will remain untouched
-// (not erased). For these not erased categories, we generate new __objc_catlist
-// entries since the parent __objc_catlist entry will be erased
-void ObjcCategoryMerger::generateCatListForNonErasedCategories(
-    const std::map<ConcatInputSection *, std::set<uint64_t>>
-        catListToErasedOffsets) {
-
-  // Go through all offsets of all __objc_catlist's that we process and if there
-  // are categories that we didn't process - generate a new __objc_catlist for
-  // each.
-  for (auto &mapEntry : catListToErasedOffsets) {
-    ConcatInputSection *catListIsec = mapEntry.first;
-    for (uint32_t catListIsecOffset = 0;
-         catListIsecOffset < catListIsec->data.size();
-         catListIsecOffset += target->wordSize) {
-      // This slot was erased, we can just skip it
-      if (mapEntry.second.count(catListIsecOffset))
-        continue;
-
-      Defined *nonErasedCatBody =
-          tryGetDefinedAtIsecOffset(catListIsec, catListIsecOffset);
-      assert(nonErasedCatBody && "Failed to relocate non-deleted category");
-
-      // Allocate data for the new __objc_catlist slot
-      auto bodyData = newSectionData(target->wordSize);
-
-      // We mark the __objc_catlist slot as belonging to the same file as the
-      // category
-      ObjFile *objFile = dyn_cast<ObjFile>(nonErasedCatBody->getFile());
-
-      ConcatInputSection *listSec = make<ConcatInputSection>(
-          *infoCategoryWriter.catListInfo.inputSection, bodyData,
-          infoCategoryWriter.catListInfo.align);
-      listSec->parent = infoCategoryWriter.catListInfo.outputSection;
-      listSec->live = true;
-      allInputSections.push_back(listSec);
-
-      std::string slotSymName = "<__objc_catlist slot for category ";
-      slotSymName += nonErasedCatBody->getName();
-      slotSymName += ">";
-
-      Defined *catListSlotSym = make<Defined>(
-          newStringData(slotSymName.c_str()), /*file=*/objFile, listSec,
-          /*value=*/0, bodyData.size(),
-          /*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/false,
-          /*includeInSymtab=*/false, /*isReferencedDynamically=*/false,
-          /*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false);
-
-      catListSlotSym->used = true;
-      objFile->symbols.push_back(catListSlotSym);
-
-      // Now link the category body into the newly created slot
-      createSymbolReference(catListSlotSym, nonErasedCatBody, 0,
-                            infoCategoryWriter.catListInfo.relocTemplate);
-    }
-  }
-}
-
-void ObjcCategoryMerger::eraseISec(ConcatInputSection *isec) {
-  isec->live = false;
-  for (auto &sym : isec->symbols)
-    sym->used = false;
-}
-
-// This fully erases the merged categories, including their body, their names,
-// their method/protocol/prop lists and the __objc_catlist entries that link to
-// them.
-void ObjcCategoryMerger::eraseMergedCategories() {
-  // Map of InputSection to a set of offsets of the categories that were merged
-  std::map<ConcatInputSection *, std::set<uint64_t>> catListToErasedOffsets;
-
-  for (auto &mapEntry : categoryMap) {
-    for (InfoInputCategory &catInfo : mapEntry.second) {
-      if (catInfo.wasMerged) {
-        eraseISec(catInfo.catListIsec);
-        catListToErasedOffsets[catInfo.catListIsec].insert(
-            catInfo.offCatListIsec);
-      }
-    }
-  }
-
-  // If there were categories that we did not erase, we need to generate a new
-  // __objc_catList that contains only the un-merged categories, and get rid of
-  // the references to the ones we merged.
-  generateCatListForNonErasedCategories(catListToErasedOffsets);
-
-  // Erase the old method lists & names of the categories that were merged
-  for (auto &mapEntry : categoryMap) {
-    for (InfoInputCategory &catInfo : mapEntry.second) {
-      if (!catInfo.wasMerged)
-        continue;
-
-      eraseISec(catInfo.catBodyIsec);
-      tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec, catLayout.nameOffset);
-      tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
-                                  catLayout.instanceMethodsOffset);
-      tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
-                                  catLayout.classMethodsOffset);
-      tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
-                                  catLayout.protocolsOffset);
-      tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
-                                  catLayout.classPropsOffset);
-      tryEraseDefinedAtIsecOffset(catInfo.catBodyIsec,
-                                  catLayout.instancePropsOffset);
-    }
-  }
-}
-
-void ObjcCategoryMerger::doMerge() {
-  collectAndValidateCategoriesData();
-
-  for (auto &entry : categoryMap)
-    if (entry.second.size() > 1)
-      // Merge all categories into a new, single category
-      mergeCategoriesIntoSingleCategory(entry.second);
-
-  // Erase all categories that were merged
-  eraseMergedCategories();
-}
-
-void ObjcCategoryMerger::doCleanup() { generatedSectionData.clear(); }
-
-StringRef ObjcCategoryMerger::newStringData(const char *str) {
-  uint32_t len = strlen(str);
-  auto &data = newSectionData(len + 1);
-  char *strData = reinterpret_cast<char *>(data.data());
-  strncpy(strData, str, len);
-  return StringRef(strData, len);
-}
-
-SmallVector<uint8_t> &ObjcCategoryMerger::newSectionData(uint32_t size) {
-  generatedSectionData.push_back(SmallVector<uint8_t>(size, 0));
-  return generatedSectionData.back();
-}
-
-} // namespace
-
-void objc::mergeCategories() {
-  TimeTraceScope timeScope("ObjcCategoryMerger");
-
-  ObjcCategoryMerger merger(inputSections);
-  merger.doMerge();
-}
-
-void objc::doCleanup() { ObjcCategoryMerger::doCleanup(); }
diff --git a/MachO/ObjC.h b/MachO/ObjC.h
index 9fbe984..4c65f9a 100644
--- a/MachO/ObjC.h
+++ b/MachO/ObjC.h
@@ -17,26 +17,14 @@
 
 namespace symbol_names {
 constexpr const char klass[] = "_OBJC_CLASS_$_";
-constexpr const char klassPropList[] = "__OBJC_$_CLASS_PROP_LIST_";
-
 constexpr const char metaclass[] = "_OBJC_METACLASS_$_";
 constexpr const char ehtype[] = "_OBJC_EHTYPE_$_";
 constexpr const char ivar[] = "_OBJC_IVAR_$_";
-constexpr const char listProprieties[] = "__OBJC_$_PROP_LIST_";
-
-constexpr const char category[] = "__OBJC_$_CATEGORY_";
-constexpr const char categoryInstanceMethods[] =
-    "__OBJC_$_CATEGORY_INSTANCE_METHODS_";
-constexpr const char categoryClassMethods[] =
-    "__OBJC_$_CATEGORY_CLASS_METHODS_";
-constexpr const char categoryProtocols[] = "__OBJC_CATEGORY_PROTOCOLS_$_";
 } // namespace symbol_names
 
 // Check for duplicate method names within related categories / classes.
 void checkCategories();
-void mergeCategories();
 
-void doCleanup();
 } // namespace objc
 
 bool hasObjCSection(llvm::MemoryBufferRef);
diff --git a/MachO/Options.td b/MachO/Options.td
index 0d8ee2a..a524e4a 100644
--- a/MachO/Options.td
+++ b/MachO/Options.td
@@ -129,12 +129,6 @@
 def check_category_conflicts : Flag<["--"], "check-category-conflicts">,
     HelpText<"Check for conflicts between category & class methods">,
     Group<grp_lld>;
-def objc_category_merging : Flag<["-"], "objc_category_merging">,
-    HelpText<"Merge Objective-C categories that share the same base class">,
-    Group<grp_lld>;
-def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">,
-    HelpText<"Do not merge Objective-C categories">,
-    Group<grp_lld>;
 def lto_debug_pass_manager: Flag<["--"], "lto-debug-pass-manager">,
     HelpText<"Debug new pass manager">, Group<grp_lld>;
 def cs_profile_generate: Flag<["--"], "cs-profile-generate">,
@@ -972,6 +966,10 @@
 def no_function_starts : Flag<["-"], "no_function_starts">,
     HelpText<"Do not create table of function start addresses">,
     Group<grp_rare>;
+def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">,
+    HelpText<"Do not merge Objective-C categories into their classes">,
+    Flags<[HelpHidden]>,
+    Group<grp_rare>;
 def object_path_lto : Separate<["-"], "object_path_lto">,
     MetaVarName<"<path>">,
     HelpText<"Retain any temporary mach-o file in <path> that would otherwise be deleted during LTO">,
diff --git a/test/MachO/objc-category-merging-complete-test.s b/test/MachO/objc-category-merging-complete-test.s
deleted file mode 100644
index 3bc3ca2..0000000
--- a/test/MachO/objc-category-merging-complete-test.s
+++ /dev/null
@@ -1,762 +0,0 @@
-# REQUIRES: aarch64
-# RUN: rm -rf %t; split-file %s %t && cd %t
-
-## Create a dylib to link against(a64_file1.dylib) and merge categories in the main binary (file2_merge_a64.exe)
-# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file1.o a64_file1.s
-# RUN: %lld -arch arm64 a64_file1.o -o a64_file1.dylib -dylib
-
-# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file2.o a64_file2.s
-# RUN: %lld -arch arm64 -o a64_file2_no_merge.exe a64_file1.dylib a64_file2.o
-# RUN: %lld -arch arm64 -o a64_file2_merge.exe -objc_category_merging a64_file1.dylib a64_file2.o
-
-# RUN: llvm-objdump --objc-meta-data --macho a64_file2_no_merge.exe | FileCheck %s --check-prefixes=NO_MERGE_CATS
-# RUN: llvm-objdump --objc-meta-data --macho a64_file2_merge.exe | FileCheck %s --check-prefixes=MERGE_CATS
-
-
-MERGE_CATS:     __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03)
-MERGE_CATS-NEXT:              name {{.*}} Category02|Category03
-MERGE_CATS:           instanceMethods
-MERGE_CATS-NEXT:           entsize 24
-MERGE_CATS-NEXT:             count 4
-MERGE_CATS-NEXT:              name {{.*}} class02InstanceMethod
-MERGE_CATS-NEXT:             types {{.*}} v16@0:8
-MERGE_CATS-NEXT:               imp -[MyBaseClass(Category02) class02InstanceMethod]
-MERGE_CATS-NEXT:              name {{.*}} myProtocol02Method
-MERGE_CATS-NEXT:             types {{.*}} v16@0:8
-MERGE_CATS-NEXT:               imp -[MyBaseClass(Category02) myProtocol02Method]
-MERGE_CATS-NEXT:              name {{.*}} class03InstanceMethod
-MERGE_CATS-NEXT:             types {{.*}} v16@0:8
-MERGE_CATS-NEXT:               imp -[MyBaseClass(Category03) class03InstanceMethod]
-MERGE_CATS-NEXT:              name {{.*}} myProtocol03Method
-MERGE_CATS-NEXT:             types {{.*}} v16@0:8
-MERGE_CATS-NEXT:               imp -[MyBaseClass(Category03) myProtocol03Method]
-MERGE_CATS-NEXT:      classMethods {{.*}}
-MERGE_CATS-NEXT:           entsize 24
-MERGE_CATS-NEXT:             count 4
-MERGE_CATS-NEXT:              name {{.*}} class02ClassMethod
-MERGE_CATS-NEXT:             types {{.*}} v16@0:8
-MERGE_CATS-NEXT:               imp +[MyBaseClass(Category02) class02ClassMethod]
-MERGE_CATS-NEXT:              name {{.*}} MyProtocol02Prop
-MERGE_CATS-NEXT:             types {{.*}} i16@0:8
-MERGE_CATS-NEXT:               imp +[MyBaseClass(Category02) MyProtocol02Prop]
-MERGE_CATS-NEXT:              name {{.*}} class03ClassMethod
-MERGE_CATS-NEXT:             types {{.*}} v16@0:8
-MERGE_CATS-NEXT:               imp +[MyBaseClass(Category03) class03ClassMethod]
-MERGE_CATS-NEXT:              name {{.*}} MyProtocol03Prop
-MERGE_CATS-NEXT:             types {{.*}} i16@0:8
-MERGE_CATS-NEXT:               imp +[MyBaseClass(Category03) MyProtocol03Prop]
-MERGE_CATS-NEXT:         protocols
-MERGE_CATS-NEXT:                      count 2
-MERGE_CATS-NEXT:              list[0] {{.*}} (struct protocol_t *)
-MERGE_CATS-NEXT:                  isa 0x0
-MERGE_CATS-NEXT:                 name {{.*}} MyProtocol02
-MERGE_CATS-NEXT:            protocols 0x0
-MERGE_CATS-NEXT:          instanceMethods
-MERGE_CATS-NEXT:               entsize 24
-MERGE_CATS-NEXT:                 count 2
-MERGE_CATS-NEXT:                  name {{.*}} myProtocol02Method
-MERGE_CATS-NEXT:                 types {{.*}} v16@0:8
-MERGE_CATS-NEXT:                   imp 0x0
-MERGE_CATS-NEXT:                  name {{.*}} MyProtocol02Prop
-MERGE_CATS-NEXT:                 types {{.*}} i16@0:8
-MERGE_CATS-NEXT:                   imp 0x0
-MERGE_CATS-NEXT:             classMethods
-MERGE_CATS-NEXT:      optionalInstanceMethods 0x0
-MERGE_CATS-NEXT:         optionalClassMethods 0x0
-MERGE_CATS-NEXT:           instanceProperties {{.*}}
-MERGE_CATS-NEXT:              list[1] {{.*}}
-MERGE_CATS-NEXT:                  isa 0x0
-MERGE_CATS-NEXT:                 name {{.*}} MyProtocol03
-MERGE_CATS-NEXT:            protocols 0x0
-MERGE_CATS-NEXT:          instanceMethods
-MERGE_CATS-NEXT:               entsize 24
-MERGE_CATS-NEXT:                 count 2
-MERGE_CATS-NEXT:                  name {{.*}} myProtocol03Method
-MERGE_CATS-NEXT:                 types {{.*}} v16@0:8
-MERGE_CATS-NEXT:                   imp 0x0
-MERGE_CATS-NEXT:                  name {{.*}} MyProtocol03Prop
-MERGE_CATS-NEXT:                 types {{.*}} i16@0:8
-MERGE_CATS-NEXT:                   imp 0x0
-MERGE_CATS-NEXT:             classMethods 0x0
-MERGE_CATS-NEXT:      optionalInstanceMethods 0x0
-MERGE_CATS-NEXT:         optionalClassMethods 0x0
-MERGE_CATS-NEXT:           instanceProperties {{.*}}
-MERGE_CATS-NEXT:      instanceProperties
-MERGE_CATS-NEXT:                    entsize 16
-MERGE_CATS-NEXT:                      count 2
-MERGE_CATS-NEXT:                 name {{.*}} MyProtocol02Prop
-MERGE_CATS-NEXT:            attributes {{.*}} Ti,R,D
-MERGE_CATS-NEXT:                 name {{.*}} MyProtocol03Prop
-MERGE_CATS-NEXT:            attributes {{.*}} Ti,R,D
-
-
-NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category02|Category03)
-NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
-NO_MERGE_CATS: instanceMethods
-NO_MERGE_CATS-NEXT: 24
-NO_MERGE_CATS-NEXT: 2
-NO_MERGE_CATS: classMethods
-NO_MERGE_CATS-NEXT: 24
-NO_MERGE_CATS-NEXT: 2
-
-
-#--- a64_file1.s
-
-## @protocol MyProtocol01
-## - (void)myProtocol01Method;
-## @property (nonatomic) int MyProtocol01Prop;
-## @end
-##
-## __attribute__((objc_root_class))
-## @interface MyBaseClass<MyProtocol01>
-## - (void)baseInstanceMethod;
-## - (void)myProtocol01Method;
-## + (void)baseClassMethod;
-## @end
-##
-## @implementation MyBaseClass
-## @synthesize MyProtocol01Prop;
-## - (void)baseInstanceMethod {}
-## - (void)myProtocol01Method {}
-## + (void)baseClassMethod {}
-## @end
-##
-## void *_objc_empty_cache;
-
-	.section	__TEXT,__text,regular,pure_instructions
-	.p2align	2                               ; -- Begin function -[MyBaseClass baseInstanceMethod]
-"-[MyBaseClass baseInstanceMethod]":    ; @"\01-[MyBaseClass baseInstanceMethod]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass myProtocol01Method]
-"-[MyBaseClass myProtocol01Method]":    ; @"\01-[MyBaseClass myProtocol01Method]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function +[MyBaseClass baseClassMethod]
-"+[MyBaseClass baseClassMethod]":       ; @"\01+[MyBaseClass baseClassMethod]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass MyProtocol01Prop]
-"-[MyBaseClass MyProtocol01Prop]":      ; @"\01-[MyBaseClass MyProtocol01Prop]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-Lloh0:
-	adrp	x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGE
-Lloh1:
-	ldrsw	x8, [x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGEOFF]
-	ldr	w0, [x0, x8]
-	ret
-	.loh AdrpLdr	Lloh0, Lloh1
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass setMyProtocol01Prop:]
-"-[MyBaseClass setMyProtocol01Prop:]":  ; @"\01-[MyBaseClass setMyProtocol01Prop:]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-Lloh2:
-	adrp	x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGE
-Lloh3:
-	ldrsw	x8, [x8, _OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop@PAGEOFF]
-	str	w2, [x0, x8]
-	ret
-	.loh AdrpLdr	Lloh2, Lloh3
-	.cfi_endproc
-                                        ; -- End function
-	.private_extern	_OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop ; @"OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop"
-	.section	__DATA,__objc_ivar
-	.globl	_OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop
-	.p2align	2, 0x0
-_OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop:
-	.long	0                               ; 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
-_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	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_:                  ; @OBJC_METH_VAR_NAME_
-	.asciz	"baseClassMethod"
-	.section	__TEXT,__objc_methtype,cstring_literals
-l_OBJC_METH_VAR_TYPE_:                  ; @OBJC_METH_VAR_TYPE_
-	.asciz	"v16@0:8"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CLASS_METHODS_MyBaseClass"
-__OBJC_$_CLASS_METHODS_MyBaseClass:
-	.long	24                              ; 0x18
-	.long	1                               ; 0x1
-	.quad	l_OBJC_METH_VAR_NAME_
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"+[MyBaseClass baseClassMethod]"
-	.section	__TEXT,__objc_classname,cstring_literals
-l_OBJC_CLASS_NAME_.1:                   ; @OBJC_CLASS_NAME_.1
-	.asciz	"MyProtocol01"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.2:                ; @OBJC_METH_VAR_NAME_.2
-	.asciz	"myProtocol01Method"
-l_OBJC_METH_VAR_NAME_.3:                ; @OBJC_METH_VAR_NAME_.3
-	.asciz	"MyProtocol01Prop"
-	.section	__TEXT,__objc_methtype,cstring_literals
-l_OBJC_METH_VAR_TYPE_.4:                ; @OBJC_METH_VAR_TYPE_.4
-	.asciz	"i16@0:8"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.5:                ; @OBJC_METH_VAR_NAME_.5
-	.asciz	"setMyProtocol01Prop:"
-	.section	__TEXT,__objc_methtype,cstring_literals
-l_OBJC_METH_VAR_TYPE_.6:                ; @OBJC_METH_VAR_TYPE_.6
-	.asciz	"v20@0:8i16"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01"
-__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01:
-	.long	24                              ; 0x18
-	.long	3                               ; 0x3
-	.quad	l_OBJC_METH_VAR_NAME_.2
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	0
-	.quad	l_OBJC_METH_VAR_NAME_.3
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.quad	0
-	.quad	l_OBJC_METH_VAR_NAME_.5
-	.quad	l_OBJC_METH_VAR_TYPE_.6
-	.quad	0
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_PROP_NAME_ATTR_:                 ; @OBJC_PROP_NAME_ATTR_
-	.asciz	"MyProtocol01Prop"
-l_OBJC_PROP_NAME_ATTR_.7:               ; @OBJC_PROP_NAME_ATTR_.7
-	.asciz	"Ti,N"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROP_LIST_MyProtocol01"
-__OBJC_$_PROP_LIST_MyProtocol01:
-	.long	16                              ; 0x10
-	.long	1                               ; 0x1
-	.quad	l_OBJC_PROP_NAME_ATTR_
-	.quad	l_OBJC_PROP_NAME_ATTR_.7
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01"
-__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01:
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.quad	l_OBJC_METH_VAR_TYPE_.6
-	.private_extern	__OBJC_PROTOCOL_$_MyProtocol01 ; @"_OBJC_PROTOCOL_$_MyProtocol01"
-	.section	__DATA,__data
-	.globl	__OBJC_PROTOCOL_$_MyProtocol01
-	.weak_definition	__OBJC_PROTOCOL_$_MyProtocol01
-	.p2align	3, 0x0
-__OBJC_PROTOCOL_$_MyProtocol01:
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_.1
-	.quad	0
-	.quad	__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol01
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	__OBJC_$_PROP_LIST_MyProtocol01
-	.long	96                              ; 0x60
-	.long	0                               ; 0x0
-	.quad	__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol01
-	.quad	0
-	.quad	0
-	.private_extern	__OBJC_LABEL_PROTOCOL_$_MyProtocol01 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol01"
-	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
-	.globl	__OBJC_LABEL_PROTOCOL_$_MyProtocol01
-	.weak_definition	__OBJC_LABEL_PROTOCOL_$_MyProtocol01
-	.p2align	3, 0x0
-__OBJC_LABEL_PROTOCOL_$_MyProtocol01:
-	.quad	__OBJC_PROTOCOL_$_MyProtocol01
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_CLASS_PROTOCOLS_$_MyBaseClass"
-__OBJC_CLASS_PROTOCOLS_$_MyBaseClass:
-	.quad	1                               ; 0x1
-	.quad	__OBJC_PROTOCOL_$_MyProtocol01
-	.quad	0
-	.p2align	3, 0x0                          ; @"_OBJC_METACLASS_RO_$_MyBaseClass"
-__OBJC_METACLASS_RO_$_MyBaseClass:
-	.long	3                               ; 0x3
-	.long	40                              ; 0x28
-	.long	40                              ; 0x28
-	.space	4
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_
-	.quad	__OBJC_$_CLASS_METHODS_MyBaseClass
-	.quad	__OBJC_CLASS_PROTOCOLS_$_MyBaseClass
-	.quad	0
-	.quad	0
-	.quad	0
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.8:                ; @OBJC_METH_VAR_NAME_.8
-	.asciz	"baseInstanceMethod"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_INSTANCE_METHODS_MyBaseClass"
-__OBJC_$_INSTANCE_METHODS_MyBaseClass:
-	.long	24                              ; 0x18
-	.long	4                               ; 0x4
-	.quad	l_OBJC_METH_VAR_NAME_.8
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass baseInstanceMethod]"
-	.quad	l_OBJC_METH_VAR_NAME_.2
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass myProtocol01Method]"
-	.quad	l_OBJC_METH_VAR_NAME_.3
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.quad	"-[MyBaseClass MyProtocol01Prop]"
-	.quad	l_OBJC_METH_VAR_NAME_.5
-	.quad	l_OBJC_METH_VAR_TYPE_.6
-	.quad	"-[MyBaseClass setMyProtocol01Prop:]"
-	.section	__TEXT,__objc_methtype,cstring_literals
-l_OBJC_METH_VAR_TYPE_.9:                ; @OBJC_METH_VAR_TYPE_.9
-	.asciz	"i"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_INSTANCE_VARIABLES_MyBaseClass"
-__OBJC_$_INSTANCE_VARIABLES_MyBaseClass:
-	.long	32                              ; 0x20
-	.long	1                               ; 0x1
-	.quad	_OBJC_IVAR_$_MyBaseClass.MyProtocol01Prop
-	.quad	l_OBJC_METH_VAR_NAME_.3
-	.quad	l_OBJC_METH_VAR_TYPE_.9
-	.long	2                               ; 0x2
-	.long	4                               ; 0x4
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_PROP_NAME_ATTR_.10:              ; @OBJC_PROP_NAME_ATTR_.10
-	.asciz	"Ti,N,VMyProtocol01Prop"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROP_LIST_MyBaseClass"
-__OBJC_$_PROP_LIST_MyBaseClass:
-	.long	16                              ; 0x10
-	.long	1                               ; 0x1
-	.quad	l_OBJC_PROP_NAME_ATTR_
-	.quad	l_OBJC_PROP_NAME_ATTR_.10
-	.p2align	3, 0x0                          ; @"_OBJC_CLASS_RO_$_MyBaseClass"
-__OBJC_CLASS_RO_$_MyBaseClass:
-	.long	2                               ; 0x2
-	.long	0                               ; 0x0
-	.long	4                               ; 0x4
-	.space	4
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_
-	.quad	__OBJC_$_INSTANCE_METHODS_MyBaseClass
-	.quad	__OBJC_CLASS_PROTOCOLS_$_MyBaseClass
-	.quad	__OBJC_$_INSTANCE_VARIABLES_MyBaseClass
-	.quad	0
-	.quad	__OBJC_$_PROP_LIST_MyBaseClass
-	.globl	__objc_empty_cache              ; @_objc_empty_cache
-.zerofill __DATA,__common,__objc_empty_cache,8,3
-	.section	__DATA,__objc_classlist,regular,no_dead_strip
-	.p2align	3, 0x0                          ; @"OBJC_LABEL_CLASS_$"
-l_OBJC_LABEL_CLASS_$:
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_MyProtocol01
-	.no_dead_strip	__OBJC_PROTOCOL_$_MyProtocol01
-	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
-L_OBJC_IMAGE_INFO:
-	.long	0
-	.long	96
-.subsections_via_symbols
-
-
-#--- a64_file2.s
-
-## @protocol MyProtocol01
-## - (void)myProtocol01Method;
-## @end
-##
-## @protocol MyProtocol02
-## - (void)myProtocol02Method;
-## @property(readonly) int MyProtocol02Prop;
-## @end
-##
-## @protocol MyProtocol03
-## - (void)myProtocol03Method;
-## @property(readonly) int MyProtocol03Prop;
-## @end
-##
-##
-## __attribute__((objc_root_class))
-## @interface MyBaseClass<MyProtocol01>
-## - (void)baseInstanceMethod;
-## - (void)myProtocol01Method;
-## + (void)baseClassMethod;
-## @end
-##
-##
-##
-## @interface MyBaseClass(Category02)<MyProtocol02>
-## - (void)class02InstanceMethod;
-## - (void)myProtocol02Method;
-## + (void)class02ClassMethod;
-## + (int)MyProtocol02Prop;
-## @end
-##
-## @implementation MyBaseClass(Category02)
-## - (void)class02InstanceMethod {}
-## - (void)myProtocol02Method {}
-## + (void)class02ClassMethod {}
-## + (int)MyProtocol02Prop { return 0;}
-## @dynamic MyProtocol02Prop;
-## @end
-##
-## @interface MyBaseClass(Category03)<MyProtocol03>
-## - (void)class03InstanceMethod;
-## - (void)myProtocol03Method;
-## + (void)class03ClassMethod;
-## + (int)MyProtocol03Prop;
-## @end
-##
-## @implementation MyBaseClass(Category03)
-## - (void)class03InstanceMethod {}
-## - (void)myProtocol03Method {}
-## + (void)class03ClassMethod {}
-## + (int)MyProtocol03Prop { return 0;}
-## @dynamic MyProtocol03Prop;
-## @end
-##
-## int main() {
-##     return 0;
-## }
-
-
-	.section	__TEXT,__text,regular,pure_instructions
-	.p2align	2                               ; -- Begin function -[MyBaseClass(Category02) class02InstanceMethod]
-"-[MyBaseClass(Category02) class02InstanceMethod]": ; @"\01-[MyBaseClass(Category02) class02InstanceMethod]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass(Category02) myProtocol02Method]
-"-[MyBaseClass(Category02) myProtocol02Method]": ; @"\01-[MyBaseClass(Category02) myProtocol02Method]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function +[MyBaseClass(Category02) class02ClassMethod]
-"+[MyBaseClass(Category02) class02ClassMethod]": ; @"\01+[MyBaseClass(Category02) class02ClassMethod]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function +[MyBaseClass(Category02) MyProtocol02Prop]
-"+[MyBaseClass(Category02) MyProtocol02Prop]": ; @"\01+[MyBaseClass(Category02) MyProtocol02Prop]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	b	_OUTLINED_FUNCTION_0
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass(Category03) class03InstanceMethod]
-"-[MyBaseClass(Category03) class03InstanceMethod]": ; @"\01-[MyBaseClass(Category03) class03InstanceMethod]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass(Category03) myProtocol03Method]
-"-[MyBaseClass(Category03) myProtocol03Method]": ; @"\01-[MyBaseClass(Category03) myProtocol03Method]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function +[MyBaseClass(Category03) class03ClassMethod]
-"+[MyBaseClass(Category03) class03ClassMethod]": ; @"\01+[MyBaseClass(Category03) class03ClassMethod]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function +[MyBaseClass(Category03) MyProtocol03Prop]
-"+[MyBaseClass(Category03) MyProtocol03Prop]": ; @"\01+[MyBaseClass(Category03) MyProtocol03Prop]"
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	b	_OUTLINED_FUNCTION_0
-	.cfi_endproc
-                                        ; -- End function
-	.globl	_main                           ; -- Begin function main
-	.p2align	2
-_main:                                  ; @main
-	.cfi_startproc
-; %bb.0:                                ; %entry
-	b	_OUTLINED_FUNCTION_0
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function OUTLINED_FUNCTION_0
-_OUTLINED_FUNCTION_0:                   ; @OUTLINED_FUNCTION_0 Tail Call
-	.cfi_startproc
-; %bb.0:
-	mov	w0, #0
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.section	__TEXT,__objc_classname,cstring_literals
-l_OBJC_CLASS_NAME_:                     ; @OBJC_CLASS_NAME_
-	.asciz	"Category02"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_:                  ; @OBJC_METH_VAR_NAME_
-	.asciz	"class02InstanceMethod"
-	.section	__TEXT,__objc_methtype,cstring_literals
-l_OBJC_METH_VAR_TYPE_:                  ; @OBJC_METH_VAR_TYPE_
-	.asciz	"v16@0:8"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.1:                ; @OBJC_METH_VAR_NAME_.1
-	.asciz	"myProtocol02Method"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02"
-__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02:
-	.long	24                              ; 0x18
-	.long	2                               ; 0x2
-	.quad	l_OBJC_METH_VAR_NAME_
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass(Category02) class02InstanceMethod]"
-	.quad	l_OBJC_METH_VAR_NAME_.1
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass(Category02) myProtocol02Method]"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.2:                ; @OBJC_METH_VAR_NAME_.2
-	.asciz	"class02ClassMethod"
-l_OBJC_METH_VAR_NAME_.3:                ; @OBJC_METH_VAR_NAME_.3
-	.asciz	"MyProtocol02Prop"
-	.section	__TEXT,__objc_methtype,cstring_literals
-l_OBJC_METH_VAR_TYPE_.4:                ; @OBJC_METH_VAR_TYPE_.4
-	.asciz	"i16@0:8"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02"
-__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02:
-	.long	24                              ; 0x18
-	.long	2                               ; 0x2
-	.quad	l_OBJC_METH_VAR_NAME_.2
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"+[MyBaseClass(Category02) class02ClassMethod]"
-	.quad	l_OBJC_METH_VAR_NAME_.3
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.quad	"+[MyBaseClass(Category02) MyProtocol02Prop]"
-	.section	__TEXT,__objc_classname,cstring_literals
-l_OBJC_CLASS_NAME_.5:                   ; @OBJC_CLASS_NAME_.5
-	.asciz	"MyProtocol02"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02"
-__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02:
-	.long	24                              ; 0x18
-	.long	2                               ; 0x2
-	.quad	l_OBJC_METH_VAR_NAME_.1
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	0
-	.quad	l_OBJC_METH_VAR_NAME_.3
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.quad	0
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_PROP_NAME_ATTR_:                 ; @OBJC_PROP_NAME_ATTR_
-	.asciz	"MyProtocol02Prop"
-l_OBJC_PROP_NAME_ATTR_.6:               ; @OBJC_PROP_NAME_ATTR_.6
-	.asciz	"Ti,R"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROP_LIST_MyProtocol02"
-__OBJC_$_PROP_LIST_MyProtocol02:
-	.long	16                              ; 0x10
-	.long	1                               ; 0x1
-	.quad	l_OBJC_PROP_NAME_ATTR_
-	.quad	l_OBJC_PROP_NAME_ATTR_.6
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02"
-__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02:
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.private_extern	__OBJC_PROTOCOL_$_MyProtocol02 ; @"_OBJC_PROTOCOL_$_MyProtocol02"
-	.section	__DATA,__data
-	.globl	__OBJC_PROTOCOL_$_MyProtocol02
-	.weak_definition	__OBJC_PROTOCOL_$_MyProtocol02
-	.p2align	3, 0x0
-__OBJC_PROTOCOL_$_MyProtocol02:
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_.5
-	.quad	0
-	.quad	__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol02
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	__OBJC_$_PROP_LIST_MyProtocol02
-	.long	96                              ; 0x60
-	.long	0                               ; 0x0
-	.quad	__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol02
-	.quad	0
-	.quad	0
-	.private_extern	__OBJC_LABEL_PROTOCOL_$_MyProtocol02 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol02"
-	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
-	.globl	__OBJC_LABEL_PROTOCOL_$_MyProtocol02
-	.weak_definition	__OBJC_LABEL_PROTOCOL_$_MyProtocol02
-	.p2align	3, 0x0
-__OBJC_LABEL_PROTOCOL_$_MyProtocol02:
-	.quad	__OBJC_PROTOCOL_$_MyProtocol02
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02"
-__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02:
-	.quad	1                               ; 0x1
-	.quad	__OBJC_PROTOCOL_$_MyProtocol02
-	.quad	0
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_PROP_NAME_ATTR_.7:               ; @OBJC_PROP_NAME_ATTR_.7
-	.asciz	"Ti,R,D"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROP_LIST_MyBaseClass_$_Category02"
-__OBJC_$_PROP_LIST_MyBaseClass_$_Category02:
-	.long	16                              ; 0x10
-	.long	1                               ; 0x1
-	.quad	l_OBJC_PROP_NAME_ATTR_
-	.quad	l_OBJC_PROP_NAME_ATTR_.7
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category02"
-__OBJC_$_CATEGORY_MyBaseClass_$_Category02:
-	.quad	l_OBJC_CLASS_NAME_
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.quad	__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02
-	.quad	__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category02
-	.quad	__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category02
-	.quad	__OBJC_$_PROP_LIST_MyBaseClass_$_Category02
-	.quad	0
-	.long	64                              ; 0x40
-	.space	4
-	.section	__TEXT,__objc_classname,cstring_literals
-l_OBJC_CLASS_NAME_.8:                   ; @OBJC_CLASS_NAME_.8
-	.asciz	"Category03"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.9:                ; @OBJC_METH_VAR_NAME_.9
-	.asciz	"class03InstanceMethod"
-l_OBJC_METH_VAR_NAME_.10:               ; @OBJC_METH_VAR_NAME_.10
-	.asciz	"myProtocol03Method"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03"
-__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03:
-	.long	24                              ; 0x18
-	.long	2                               ; 0x2
-	.quad	l_OBJC_METH_VAR_NAME_.9
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass(Category03) class03InstanceMethod]"
-	.quad	l_OBJC_METH_VAR_NAME_.10
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass(Category03) myProtocol03Method]"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.11:               ; @OBJC_METH_VAR_NAME_.11
-	.asciz	"class03ClassMethod"
-l_OBJC_METH_VAR_NAME_.12:               ; @OBJC_METH_VAR_NAME_.12
-	.asciz	"MyProtocol03Prop"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03"
-__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03:
-	.long	24                              ; 0x18
-	.long	2                               ; 0x2
-	.quad	l_OBJC_METH_VAR_NAME_.11
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"+[MyBaseClass(Category03) class03ClassMethod]"
-	.quad	l_OBJC_METH_VAR_NAME_.12
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.quad	"+[MyBaseClass(Category03) MyProtocol03Prop]"
-	.section	__TEXT,__objc_classname,cstring_literals
-l_OBJC_CLASS_NAME_.13:                  ; @OBJC_CLASS_NAME_.13
-	.asciz	"MyProtocol03"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03"
-__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03:
-	.long	24                              ; 0x18
-	.long	2                               ; 0x2
-	.quad	l_OBJC_METH_VAR_NAME_.10
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	0
-	.quad	l_OBJC_METH_VAR_NAME_.12
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.quad	0
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_PROP_NAME_ATTR_.14:              ; @OBJC_PROP_NAME_ATTR_.14
-	.asciz	"MyProtocol03Prop"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROP_LIST_MyProtocol03"
-__OBJC_$_PROP_LIST_MyProtocol03:
-	.long	16                              ; 0x10
-	.long	1                               ; 0x1
-	.quad	l_OBJC_PROP_NAME_ATTR_.14
-	.quad	l_OBJC_PROP_NAME_ATTR_.6
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03"
-__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03:
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	l_OBJC_METH_VAR_TYPE_.4
-	.private_extern	__OBJC_PROTOCOL_$_MyProtocol03 ; @"_OBJC_PROTOCOL_$_MyProtocol03"
-	.section	__DATA,__data
-	.globl	__OBJC_PROTOCOL_$_MyProtocol03
-	.weak_definition	__OBJC_PROTOCOL_$_MyProtocol03
-	.p2align	3, 0x0
-__OBJC_PROTOCOL_$_MyProtocol03:
-	.quad	0
-	.quad	l_OBJC_CLASS_NAME_.13
-	.quad	0
-	.quad	__OBJC_$_PROTOCOL_INSTANCE_METHODS_MyProtocol03
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	__OBJC_$_PROP_LIST_MyProtocol03
-	.long	96                              ; 0x60
-	.long	0                               ; 0x0
-	.quad	__OBJC_$_PROTOCOL_METHOD_TYPES_MyProtocol03
-	.quad	0
-	.quad	0
-	.private_extern	__OBJC_LABEL_PROTOCOL_$_MyProtocol03 ; @"_OBJC_LABEL_PROTOCOL_$_MyProtocol03"
-	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
-	.globl	__OBJC_LABEL_PROTOCOL_$_MyProtocol03
-	.weak_definition	__OBJC_LABEL_PROTOCOL_$_MyProtocol03
-	.p2align	3, 0x0
-__OBJC_LABEL_PROTOCOL_$_MyProtocol03:
-	.quad	__OBJC_PROTOCOL_$_MyProtocol03
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03"
-__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03:
-	.quad	1                               ; 0x1
-	.quad	__OBJC_PROTOCOL_$_MyProtocol03
-	.quad	0
-	.p2align	3, 0x0                          ; @"_OBJC_$_PROP_LIST_MyBaseClass_$_Category03"
-__OBJC_$_PROP_LIST_MyBaseClass_$_Category03:
-	.long	16                              ; 0x10
-	.long	1                               ; 0x1
-	.quad	l_OBJC_PROP_NAME_ATTR_.14
-	.quad	l_OBJC_PROP_NAME_ATTR_.7
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category03"
-__OBJC_$_CATEGORY_MyBaseClass_$_Category03:
-	.quad	l_OBJC_CLASS_NAME_.8
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.quad	__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category03
-	.quad	__OBJC_$_CATEGORY_CLASS_METHODS_MyBaseClass_$_Category03
-	.quad	__OBJC_CATEGORY_PROTOCOLS_$_MyBaseClass_$_Category03
-	.quad	__OBJC_$_PROP_LIST_MyBaseClass_$_Category03
-	.quad	0
-	.long	64                              ; 0x40
-	.space	4
-	.section	__DATA,__objc_catlist,regular,no_dead_strip
-	.p2align	3, 0x0                          ; @"OBJC_LABEL_CATEGORY_$"
-l_OBJC_LABEL_CATEGORY_$:
-	.quad	__OBJC_$_CATEGORY_MyBaseClass_$_Category02
-	.quad	__OBJC_$_CATEGORY_MyBaseClass_$_Category03
-	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_MyProtocol02
-	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_MyProtocol03
-	.no_dead_strip	__OBJC_PROTOCOL_$_MyProtocol02
-	.no_dead_strip	__OBJC_PROTOCOL_$_MyProtocol03
-	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
-L_OBJC_IMAGE_INFO:
-	.long	0
-	.long	96
-.subsections_via_symbols
diff --git a/test/MachO/objc-category-merging-extern-class-minimal.s b/test/MachO/objc-category-merging-extern-class-minimal.s
deleted file mode 100644
index ede7ef5..0000000
--- a/test/MachO/objc-category-merging-extern-class-minimal.s
+++ /dev/null
@@ -1,155 +0,0 @@
-# REQUIRES: aarch64
-# RUN: rm -rf %t; split-file %s %t && cd %t
-
-## Create a dylib with a fake base class to link against
-# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_fakedylib.o a64_fakedylib.s
-# RUN: %lld -arch arm64 a64_fakedylib.o -o a64_fakedylib.dylib -dylib
-
-## Create our main testing dylib - linking against the fake dylib above
-# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal.o merge_cat_minimal.s
-# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o
-# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o
-
-## Now verify that the flag caused category merging to happen appropriatelly
-# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_CATS
-# RUN: llvm-objdump --objc-meta-data --macho merge_cat_minimal_merge.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 the merged cateogry is there, in the correct format
-MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02)
-MERGE_CATS-NEXT:   name {{.*}} Category01|Category02
-MERGE_CATS:       instanceMethods
-MERGE_CATS-NEXT:  24
-MERGE_CATS-NEXT:  2
-MERGE_CATS-NEXT:   name {{.*}} cat01_InstanceMethod
-MERGE_CATS-NEXT:  types {{.*}} v16@0:8
-MERGE_CATS-NEXT:    imp -[MyBaseClass(Category01) cat01_InstanceMethod]
-MERGE_CATS-NEXT:   name {{.*}} cat02_InstanceMethod
-MERGE_CATS-NEXT:  types {{.*}} v16@0:8
-MERGE_CATS-NEXT:    imp -[MyBaseClass(Category02) cat02_InstanceMethod]
-MERGE_CATS-NEXT:         classMethods 0x0
-MERGE_CATS-NEXT:            protocols 0x0
-MERGE_CATS-NEXT:   instanceProperties 0x0
-
-#### Check merge categories disabled ###
-# Check that the merged category is not there
-NO_MERGE_CATS-NOT: __OBJC_$_CATEGORY_MyBaseClass_$_(Category01|Category02)
-
-# Check that the original categories are there
-NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category01
-NO_MERGE_CATS: __OBJC_$_CATEGORY_MyBaseClass_$_Category02
-
-
-
-#--- a64_fakedylib.s
-
-    .section    __DATA,__objc_data
-    .globl    _OBJC_CLASS_$_MyBaseClass
-_OBJC_CLASS_$_MyBaseClass:
-    .quad    0
-
-#--- merge_cat_minimal.s
-
-;  ================== Generated from ObjC: ==================
-; __attribute__((objc_root_class))
-; @interface MyBaseClass
-; - (void)baseInstanceMethod;
-; @end
-;
-; @interface MyBaseClass(Category01)
-; - (void)cat01_InstanceMethod;
-; @end
-;
-; @implementation MyBaseClass(Category01)
-; - (void)cat01_InstanceMethod {}
-; @end
-;
-; @interface MyBaseClass(Category02)
-; - (void)cat02_InstanceMethod;
-; @end
-;
-; @implementation MyBaseClass(Category02)
-; - (void)cat02_InstanceMethod {}
-; @end
-;  ================== Generated from ObjC: ==================
-
-	.section	__TEXT,__text,regular,pure_instructions
-	.p2align	2                               ; -- Begin function -[MyBaseClass(Category01) cat01_InstanceMethod]
-"-[MyBaseClass(Category01) cat01_InstanceMethod]": ; @"\01-[MyBaseClass(Category01) cat01_InstanceMethod]"
-	.cfi_startproc
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.p2align	2                               ; -- Begin function -[MyBaseClass(Category02) cat02_InstanceMethod]
-"-[MyBaseClass(Category02) cat02_InstanceMethod]": ; @"\01-[MyBaseClass(Category02) cat02_InstanceMethod]"
-	.cfi_startproc
-	ret
-	.cfi_endproc
-                                        ; -- End function
-	.section	__TEXT,__objc_classname,cstring_literals
-l_OBJC_CLASS_NAME_:                     ; @OBJC_CLASS_NAME_
-	.asciz	"Category01"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_:                  ; @OBJC_METH_VAR_NAME_
-	.asciz	"cat01_InstanceMethod"
-	.section	__TEXT,__objc_methtype,cstring_literals
-l_OBJC_METH_VAR_TYPE_:                  ; @OBJC_METH_VAR_TYPE_
-	.asciz	"v16@0:8"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01"
-__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01:
-	.long	24                              ; 0x18
-	.long	1                               ; 0x1
-	.quad	l_OBJC_METH_VAR_NAME_
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass(Category01) cat01_InstanceMethod]"
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category01"
-__OBJC_$_CATEGORY_MyBaseClass_$_Category01:
-	.quad	l_OBJC_CLASS_NAME_
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.quad	__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category01
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	0
-	.long	64                              ; 0x40
-	.space	4
-	.section	__TEXT,__objc_classname,cstring_literals
-l_OBJC_CLASS_NAME_.1:                   ; @OBJC_CLASS_NAME_.1
-	.asciz	"Category02"
-	.section	__TEXT,__objc_methname,cstring_literals
-l_OBJC_METH_VAR_NAME_.2:                ; @OBJC_METH_VAR_NAME_.2
-	.asciz	"cat02_InstanceMethod"
-	.section	__DATA,__objc_const
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02"
-__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02:
-	.long	24                              ; 0x18
-	.long	1                               ; 0x1
-	.quad	l_OBJC_METH_VAR_NAME_.2
-	.quad	l_OBJC_METH_VAR_TYPE_
-	.quad	"-[MyBaseClass(Category02) cat02_InstanceMethod]"
-	.p2align	3, 0x0                          ; @"_OBJC_$_CATEGORY_MyBaseClass_$_Category02"
-__OBJC_$_CATEGORY_MyBaseClass_$_Category02:
-	.quad	l_OBJC_CLASS_NAME_.1
-	.quad	_OBJC_CLASS_$_MyBaseClass
-	.quad	__OBJC_$_CATEGORY_INSTANCE_METHODS_MyBaseClass_$_Category02
-	.quad	0
-	.quad	0
-	.quad	0
-	.quad	0
-	.long	64                              ; 0x40
-	.space	4
-	.section	__DATA,__objc_catlist,regular,no_dead_strip
-	.p2align	3, 0x0                          ; @"OBJC_LABEL_CATEGORY_$"
-l_OBJC_LABEL_CATEGORY_$:
-	.quad	__OBJC_$_CATEGORY_MyBaseClass_$_Category01
-	.quad	__OBJC_$_CATEGORY_MyBaseClass_$_Category02
-	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
-L_OBJC_IMAGE_INFO:
-	.long	0
-	.long	96
-.subsections_via_symbols