@@ -495,6 +495,7 @@ class ObjcCategoryMerger {
495
495
Defined *tryGetDefinedAtIsecOffset (const ConcatInputSection *isec,
496
496
uint32_t offset);
497
497
Defined *getClassRo (const Defined *classSym, bool getMetaRo);
498
+ SourceLanguage getClassSymSourceLang (const Defined *classSym);
498
499
void mergeCategoriesIntoBaseClass (const Defined *baseClass,
499
500
std::vector<InfoInputCategory> &categories);
500
501
void eraseSymbolAtIsecOffset (ConcatInputSection *isec, uint32_t offset);
@@ -1377,21 +1378,37 @@ void objc::mergeCategories() {
1377
1378
1378
1379
void objc::doCleanup () { ObjcCategoryMerger::doCleanup (); }
1379
1380
1381
+ ObjcCategoryMerger::SourceLanguage
1382
+ ObjcCategoryMerger::getClassSymSourceLang (const Defined *classSym) {
1383
+ if (classSym->getName ().starts_with (objc::symbol_names::swift_objc_klass))
1384
+ return SourceLanguage::Swift;
1385
+
1386
+ // If the symbol name matches the ObjC prefix, we don't necessarely know this
1387
+ // comes from ObjC, since Swift creates ObjC-like alias symbols for some Swift
1388
+ // classes. Ex:
1389
+ // .globl _OBJC_CLASS_$__TtC11MyTestClass11MyTestClass
1390
+ // .private_extern _OBJC_CLASS_$__TtC11MyTestClass11MyTestClass
1391
+ // .set _OBJC_CLASS_$__TtC11MyTestClass11MyTestClass, _$s11MyTestClassAACN
1392
+ //
1393
+ // So we scan for symbols with the same address and check for the Swift class
1394
+ if (classSym->getName ().starts_with (objc::symbol_names::klass)) {
1395
+ for (auto &sym : classSym->originalIsec ->symbols )
1396
+ if (sym->value == classSym->value )
1397
+ if (sym->getName ().starts_with (objc::symbol_names::swift_objc_klass))
1398
+ return SourceLanguage::Swift;
1399
+ return SourceLanguage::ObjC;
1400
+ }
1401
+
1402
+ llvm_unreachable (" Unexpected class symbol name during category merging" );
1403
+ }
1380
1404
void ObjcCategoryMerger::mergeCategoriesIntoBaseClass (
1381
1405
const Defined *baseClass, std::vector<InfoInputCategory> &categories) {
1382
1406
assert (categories.size () >= 1 && " Expected at least one category to merge" );
1383
1407
1384
1408
// Collect all the info from the categories
1385
1409
ClassExtensionInfo extInfo (catLayout);
1386
1410
extInfo.baseClass = baseClass;
1387
-
1388
- if (baseClass->getName ().starts_with (objc::symbol_names::klass))
1389
- extInfo.baseClassSourceLanguage = SourceLanguage::ObjC;
1390
- else if (baseClass->getName ().starts_with (
1391
- objc::symbol_names::swift_objc_klass))
1392
- extInfo.baseClassSourceLanguage = SourceLanguage::Swift;
1393
- else
1394
- llvm_unreachable (" Unexpected base class symbol name" );
1411
+ extInfo.baseClassSourceLanguage = getClassSymSourceLang (baseClass);
1395
1412
1396
1413
for (auto &catInfo : categories) {
1397
1414
parseCatInfoToExtInfo (catInfo, extInfo);
0 commit comments