@@ -1148,11 +1148,21 @@ class TypeRefBuilder {
11481148 }
11491149
11501150 // / Extract conforming type's name from a Conformance Descriptor
1151- llvm::Optional<std::string> getConformingTypeName (
1151+ // / Returns a pair of (mangledTypeName, fullyQualifiedTypeName)
1152+ llvm::Optional<std::pair<std::string, std::string>> getConformingTypeName (
11521153 const uintptr_t conformanceDescriptorAddress,
11531154 const ExternalProtocolConformanceDescriptor<
11541155 ObjCInteropKind, PointerSize> &conformanceDescriptor) {
11551156 std::string typeName;
1157+ std::string mangledTypeName = " " ;
1158+
1159+ // If this is a conformance added to an ObjC class, detect that here and return class name
1160+ if (conformanceDescriptor.getTypeKind () == TypeReferenceKind::DirectObjCClassName) {
1161+ auto className = conformanceDescriptor.getDirectObjCClassName ();
1162+ typeName = MANGLING_MODULE_OBJC.str () + std::string (" ." ) + className;
1163+ return std::make_pair (mangledTypeName, typeName);
1164+ }
1165+
11561166 // Compute the address of the type descriptor as follows:
11571167 // - Compute the address of the TypeRef field in the protocol
11581168 // descriptor
@@ -1179,6 +1189,21 @@ class TypeRefBuilder {
11791189 (const char *)contextDescriptorFieldAddress,
11801190 (int32_t )*contextDescriptorOffset);
11811191
1192+ // Instead of a type descriptor this may just be a symbol reference, check that first
1193+ if (auto symbol = OpaquePointerReader (remote::RemoteAddress (contextTypeDescriptorAddress),
1194+ PointerSize)) {
1195+ if (!symbol->getSymbol ().empty ()) {
1196+ mangledTypeName = symbol->getSymbol ().str ();
1197+ Demangle::Context Ctx;
1198+ auto demangledRoot =
1199+ Ctx.demangleSymbolAsNode (mangledTypeName);
1200+ assert (demangledRoot->getKind () == Node::Kind::Global);
1201+ typeName =
1202+ nodeToString (demangledRoot->getChild (0 )->getChild (0 ));
1203+ return std::make_pair (mangledTypeName, typeName);
1204+ }
1205+ }
1206+
11821207 auto contextTypeDescriptorBytes = OpaqueByteReader (
11831208 remote::RemoteAddress (contextTypeDescriptorAddress),
11841209 sizeof (ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
@@ -1213,7 +1238,7 @@ class TypeRefBuilder {
12131238 typeName = optionalParentName.getValue () + " ." + typeName;
12141239 }
12151240
1216- return typeName;
1241+ return std::make_pair (mangledTypeName, typeName) ;
12171242 }
12181243
12191244 // / Extract protocol name from a Conformance Descriptor
@@ -1317,9 +1342,9 @@ class TypeRefBuilder {
13171342 (const ExternalProtocolConformanceDescriptor<
13181343 ObjCInteropKind, PointerSize> *)descriptorBytes.get ();
13191344
1320- auto optionalConformingTypeName = getConformingTypeName (
1345+ auto optionalConformingTypeNamePair = getConformingTypeName (
13211346 conformanceDescriptorAddress, *conformanceDescriptorPtr);
1322- if (!optionalConformingTypeName .hasValue ())
1347+ if (!optionalConformingTypeNamePair .hasValue ())
13231348 return llvm::None;
13241349
13251350 auto optionalConformanceProtocol = getConformanceProtocolName (
@@ -1328,15 +1353,18 @@ class TypeRefBuilder {
13281353 return llvm::None;
13291354
13301355 std::string mangledTypeName;
1331- auto it =
1332- typeNameToManglingMap.find (optionalConformingTypeName.getValue ());
1333- if (it != typeNameToManglingMap.end ()) {
1334- mangledTypeName = it->second ;
1356+ if (optionalConformingTypeNamePair.getValue ().first .empty ()) {
1357+ auto it = typeNameToManglingMap.find (optionalConformingTypeNamePair.getValue ().second );
1358+ if (it != typeNameToManglingMap.end ()) {
1359+ mangledTypeName = it->second ;
1360+ } else {
1361+ mangledTypeName = " " ;
1362+ }
13351363 } else {
1336- mangledTypeName = " " ;
1364+ mangledTypeName = optionalConformingTypeNamePair. getValue (). first ;
13371365 }
13381366
1339- return ProtocolConformanceInfo{optionalConformingTypeName .getValue (),
1367+ return ProtocolConformanceInfo{optionalConformingTypeNamePair .getValue (). second ,
13401368 optionalConformanceProtocol.getValue (),
13411369 mangledTypeName};
13421370 }
0 commit comments