@@ -22,15 +22,21 @@ using namespace llvm::MachO;
2222Record *RecordsSlice::addRecord (StringRef Name, SymbolFlags Flags,
2323 GlobalRecord::Kind GV, RecordLinkage Linkage) {
2424 // Find a specific Record type to capture.
25- auto [APIName, SymKind] = parseSymbol (Name, Flags );
25+ auto [APIName, SymKind, InterfaceType ] = parseSymbol (Name);
2626 Name = APIName;
2727 switch (SymKind) {
2828 case EncodeKind::GlobalSymbol:
2929 return addGlobal (Name, Linkage, GV, Flags);
3030 case EncodeKind::ObjectiveCClass:
31- return addObjCInterface (Name, Linkage);
32- case EncodeKind::ObjectiveCClassEHType:
33- return addObjCInterface (Name, Linkage, /* HasEHType=*/ true );
31+ return addObjCInterface (Name, Linkage, InterfaceType);
32+ case EncodeKind::ObjectiveCClassEHType: {
33+ ObjCInterfaceRecord *Rec = addObjCInterface (Name, Linkage, InterfaceType);
34+ // When classes without ehtype are used in try/catch blocks
35+ // a weak-defined symbol is exported.
36+ if ((Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined)
37+ updateFlags (Rec, SymbolFlags::WeakDefined);
38+ return Rec;
39+ }
3440 case EncodeKind::ObjectiveCInstanceVariable: {
3541 auto [Super, IVar] = Name.split (' .' );
3642 // Attempt to find super class.
@@ -88,6 +94,39 @@ GlobalRecord *RecordsSlice::findGlobal(StringRef Name,
8894 return Record;
8995}
9096
97+ RecordLinkage
98+ ObjCInterfaceRecord::getLinkageForSymbol (ObjCIFSymbolKind CurrType) const {
99+ assert (CurrType <= ObjCIFSymbolKind::EHType &&
100+ " expected single ObjCIFSymbolKind enum value" );
101+ if (CurrType == ObjCIFSymbolKind::Class)
102+ return Linkages.Class ;
103+
104+ if (CurrType == ObjCIFSymbolKind::MetaClass)
105+ return Linkages.MetaClass ;
106+
107+ if (CurrType == ObjCIFSymbolKind::EHType)
108+ return Linkages.EHType ;
109+
110+ llvm_unreachable (" unexpected ObjCIFSymbolKind" );
111+ }
112+
113+ void ObjCInterfaceRecord::updateLinkageForSymbols (ObjCIFSymbolKind SymType,
114+ RecordLinkage Link) {
115+ if ((SymType & ObjCIFSymbolKind::Class) == ObjCIFSymbolKind::Class)
116+ Linkages.Class = std::max (Link, Linkages.Class );
117+ if ((SymType & ObjCIFSymbolKind::MetaClass) == ObjCIFSymbolKind::MetaClass)
118+ Linkages.MetaClass = std::max (Link, Linkages.MetaClass );
119+ if ((SymType & ObjCIFSymbolKind::EHType) == ObjCIFSymbolKind::EHType)
120+ Linkages.EHType = std::max (Link, Linkages.EHType );
121+
122+ // Obj-C Classes represent multiple symbols that could have competing
123+ // linkages, in this case assign the largest one, when querying the linkage of
124+ // the record itself. This allows visitors pick whether they want to account
125+ // for complete symbol information.
126+ Linkage =
127+ std::max (Linkages.Class , std::max (Linkages.MetaClass , Linkages.EHType ));
128+ }
129+
91130ObjCInterfaceRecord *RecordsSlice::findObjCInterface (StringRef Name) const {
92131 return findRecord<ObjCInterfaceRecord>(Name, Classes);
93132}
@@ -152,21 +191,17 @@ GlobalRecord *RecordsSlice::addGlobal(StringRef Name, RecordLinkage Linkage,
152191
153192ObjCInterfaceRecord *RecordsSlice::addObjCInterface (StringRef Name,
154193 RecordLinkage Linkage,
155- bool HasEHType ) {
194+ ObjCIFSymbolKind SymType ) {
156195 Name = copyString (Name);
157196 auto Result = Classes.insert ({Name, nullptr });
158- if (Result.second ) {
197+ if (Result.second )
159198 Result.first ->second =
160- std::make_unique<ObjCInterfaceRecord>(Name, Linkage, HasEHType);
161- } else {
162- // ObjC classes represent multiple symbols that could have competing
163- // linkages, in those cases assign the largest one.
164- if (Linkage >= RecordLinkage::Rexported)
165- updateLinkage (Result.first ->second .get (), Linkage);
166- }
167-
199+ std::make_unique<ObjCInterfaceRecord>(Name, Linkage, SymType);
200+ else
201+ Result.first ->second ->updateLinkageForSymbols (SymType, Linkage);
168202 return Result.first ->second .get ();
169203}
204+
170205SymbolFlags Record::mergeFlags (SymbolFlags Flags, RecordLinkage Linkage) {
171206 // Add Linkage properties into Flags.
172207 switch (Linkage) {
0 commit comments