Skip to content

Commit 2f4049a

Browse files
committed
Factor out gathering of context names into a separate reader type inside 'TypeRefBuilder'
1 parent cfad246 commit 2f4049a

File tree

1 file changed

+165
-120
lines changed

1 file changed

+165
-120
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 165 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -999,9 +999,8 @@ class TypeRefBuilder {
999999
}
10001000

10011001
///
1002-
/// Dumping typerefs, field declarations, associated types
1002+
/// Dumping typerefs, field declarations, builtin types, captures, multi-payload enums
10031003
///
1004-
10051004
void dumpTypeRef(RemoteRef<char> MangledName, std::ostream &stream,
10061005
bool printTypeName = false);
10071006
FieldTypeCollectionResult collectFieldTypes(llvm::Optional<std::string> forMangledTypeName);
@@ -1012,43 +1011,151 @@ class TypeRefBuilder {
10121011
void dumpCaptureSection(std::ostream &stream);
10131012
void dumpMultiPayloadEnumSection(std::ostream &stream);
10141013

1015-
///
1016-
/// Extraction of protocol conformances
1017-
///
1018-
10191014
private:
1020-
/// Reader of protocol descriptors from Images
1015+
struct ContextNameInfo {
1016+
std::string name;
1017+
uintptr_t descriptorAddress;
1018+
bool isAnonymous;
1019+
1020+
~ContextNameInfo() {}
1021+
};
1022+
10211023
template <template <typename Runtime> class ObjCInteropKind,
10221024
unsigned PointerSize>
1023-
struct ProtocolConformanceDescriptorReader {
1025+
struct QualifiedContextNameReader {
10241026
std::string Error;
10251027
ByteReader OpaqueByteReader;
10261028
StringReader OpaqueStringReader;
10271029
PointerReader OpaquePointerReader;
10281030
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
10291031

1030-
ProtocolConformanceDescriptorReader(ByteReader byteReader,
1031-
StringReader stringReader,
1032-
PointerReader pointerReader,
1033-
DynamicSymbolResolver dynamicSymbolResolver)
1032+
QualifiedContextNameReader(ByteReader byteReader,
1033+
StringReader stringReader,
1034+
PointerReader pointerReader,
1035+
DynamicSymbolResolver dynamicSymbolResolver)
10341036
: Error(""), OpaqueByteReader(byteReader),
10351037
OpaqueStringReader(stringReader),
10361038
OpaquePointerReader(pointerReader),
10371039
OpaqueDynamicSymbolResolver(dynamicSymbolResolver) {}
10381040

1039-
struct ContextNameInfo {
1040-
std::string name;
1041-
uintptr_t descriptorAddress;
1042-
bool isAnonymous;
1041+
llvm::Optional<std::string> readProtocolNameFromProtocolDescriptor(
1042+
uintptr_t protocolDescriptorAddress) {
1043+
std::string protocolName;
1044+
auto protocolDescriptorBytes = OpaqueByteReader(
1045+
remote::RemoteAddress(protocolDescriptorAddress),
1046+
sizeof(ExternalProtocolDescriptor<ObjCInteropKind, PointerSize>));
1047+
if (!protocolDescriptorBytes.get()) {
1048+
Error = "Error reading protocol descriptor.";
1049+
return llvm::None;
1050+
}
1051+
const ExternalProtocolDescriptor<ObjCInteropKind, PointerSize>
1052+
*protocolDescriptor =
1053+
(const ExternalProtocolDescriptor<ObjCInteropKind, PointerSize> *)
1054+
protocolDescriptorBytes.get();
10431055

1044-
~ContextNameInfo() {}
1045-
};
1056+
// Compute the address of the protocol descriptor's name field and read
1057+
// the offset
1058+
auto protocolNameOffsetAddress = detail::applyRelativeOffset(
1059+
(const char *)protocolDescriptorAddress,
1060+
(int32_t)protocolDescriptor->getNameOffset());
1061+
auto protocolNameOffsetBytes = OpaqueByteReader(
1062+
remote::RemoteAddress(protocolNameOffsetAddress), sizeof(uint32_t));
1063+
if (!protocolNameOffsetBytes.get()) {
1064+
Error = "Failed to read type name offset in a protocol descriptor.";
1065+
return llvm::None;
1066+
}
1067+
auto protocolNameOffset = (const uint32_t *)protocolNameOffsetBytes.get();
10461068

1047-
bool isModuleDescriptor(
1048-
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
1049-
*contextDescriptor) {
1050-
return isa<ExternalModuleContextDescriptor<ObjCInteropKind, PointerSize>>(
1051-
contextDescriptor);
1069+
// Using the offset above, compute the address of the name field itsel
1070+
// and read it.
1071+
auto protocolNameAddress =
1072+
detail::applyRelativeOffset((const char *)protocolNameOffsetAddress,
1073+
(int32_t)*protocolNameOffset);
1074+
OpaqueStringReader(remote::RemoteAddress(protocolNameAddress),
1075+
protocolName);
1076+
return protocolName;
1077+
}
1078+
1079+
llvm::Optional<std::string> readTypeNameFromTypeDescriptor(
1080+
const ExternalTypeContextDescriptor<ObjCInteropKind, PointerSize>
1081+
*typeDescriptor,
1082+
uintptr_t typeDescriptorAddress) {
1083+
auto typeNameOffsetAddress =
1084+
detail::applyRelativeOffset((const char *)typeDescriptorAddress,
1085+
(int32_t)typeDescriptor->getNameOffset());
1086+
auto typeNameOffsetBytes = OpaqueByteReader(
1087+
remote::RemoteAddress(typeNameOffsetAddress), sizeof(uint32_t));
1088+
if (!typeNameOffsetBytes.get()) {
1089+
Error = "Failed to read type name offset in a type descriptor.";
1090+
return llvm::None;
1091+
}
1092+
auto typeNameOffset = (const uint32_t *)typeNameOffsetBytes.get();
1093+
auto typeNameAddress = detail::applyRelativeOffset(
1094+
(const char *)typeNameOffsetAddress, (int32_t)*typeNameOffset);
1095+
std::string typeName;
1096+
OpaqueStringReader(remote::RemoteAddress(typeNameAddress), typeName);
1097+
return typeName;
1098+
}
1099+
1100+
llvm::Optional<std::string> readModuleNameFromModuleDescriptor(
1101+
const ExternalModuleContextDescriptor<ObjCInteropKind, PointerSize>
1102+
*moduleDescriptor,
1103+
uintptr_t moduleDescriptorAddress) {
1104+
auto parentNameOffsetAddress = detail::applyRelativeOffset(
1105+
(const char *)moduleDescriptorAddress,
1106+
(int32_t)moduleDescriptor->getNameOffset());
1107+
auto parentNameOffsetBytes = OpaqueByteReader(
1108+
remote::RemoteAddress(parentNameOffsetAddress), sizeof(uint32_t));
1109+
if (!parentNameOffsetBytes.get()) {
1110+
Error = "Failed to read parent name offset in a module descriptor.";
1111+
return llvm::None;
1112+
}
1113+
auto parentNameOffset = (const uint32_t *)parentNameOffsetBytes.get();
1114+
auto parentNameAddress = detail::applyRelativeOffset(
1115+
(const char *)parentNameOffsetAddress, (int32_t)*parentNameOffset);
1116+
std::string parentName;
1117+
OpaqueStringReader(remote::RemoteAddress(parentNameAddress), parentName);
1118+
return parentName;
1119+
}
1120+
1121+
llvm::Optional<std::string> readAnonymousNameFromAnonymousDescriptor(
1122+
const ExternalAnonymousContextDescriptor<ObjCInteropKind, PointerSize>
1123+
*anonymousDescriptor,
1124+
uintptr_t anonymousDescriptorAddress) {
1125+
if (!anonymousDescriptor->hasMangledName()) {
1126+
std::stringstream stream;
1127+
stream << "(unknown context at $" << std::hex
1128+
<< anonymousDescriptorAddress << ")";
1129+
return stream.str();
1130+
}
1131+
return llvm::None;
1132+
}
1133+
1134+
llvm::Optional<std::string>
1135+
readFullyQualifiedProtocolNameFromProtocolDescriptor(
1136+
uintptr_t protocolDescriptorAddress) {
1137+
llvm::Optional<std::string> protocolName =
1138+
readProtocolNameFromProtocolDescriptor(protocolDescriptorAddress);
1139+
1140+
// Read the protocol conformance descriptor itself
1141+
auto protocolContextDescriptorBytes = OpaqueByteReader(
1142+
remote::RemoteAddress(protocolDescriptorAddress),
1143+
sizeof(ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
1144+
if (!protocolContextDescriptorBytes.get()) {
1145+
// Error = "Failed to read context (protocol) descriptor.";
1146+
return llvm::None;
1147+
}
1148+
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
1149+
*protocolDescriptor =
1150+
(const ExternalContextDescriptor<ObjCInteropKind, PointerSize> *)
1151+
protocolContextDescriptorBytes.get();
1152+
1153+
std::vector<ContextNameInfo> contextNameChain;
1154+
contextNameChain.push_back(ContextNameInfo{
1155+
protocolName.getValue(), protocolDescriptorAddress, false});
1156+
getParentContextChain(protocolDescriptorAddress, protocolDescriptor,
1157+
contextNameChain);
1158+
return constructFullyQualifiedNameFromContextChain(contextNameChain);
10521159
}
10531160

10541161
uintptr_t getParentDescriptorAddress(
@@ -1105,6 +1212,13 @@ class TypeRefBuilder {
11051212
}
11061213
}
11071214

1215+
bool isModuleDescriptor(
1216+
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
1217+
*contextDescriptor) {
1218+
return isa<ExternalModuleContextDescriptor<ObjCInteropKind, PointerSize>>(
1219+
contextDescriptor);
1220+
}
1221+
11081222
void getParentContextChain(
11091223
uintptr_t contextDescriptorAddress,
11101224
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
@@ -1166,61 +1280,6 @@ class TypeRefBuilder {
11661280
return;
11671281
}
11681282

1169-
llvm::Optional<std::string> readTypeNameFromTypeDescriptor(
1170-
const ExternalTypeContextDescriptor<ObjCInteropKind, PointerSize>
1171-
*typeDescriptor,
1172-
uintptr_t typeDescriptorAddress) {
1173-
auto typeNameOffsetAddress =
1174-
detail::applyRelativeOffset((const char *)typeDescriptorAddress,
1175-
(int32_t)typeDescriptor->getNameOffset());
1176-
auto typeNameOffsetBytes = OpaqueByteReader(
1177-
remote::RemoteAddress(typeNameOffsetAddress), sizeof(uint32_t));
1178-
if (!typeNameOffsetBytes.get()) {
1179-
Error = "Failed to read type name offset in a type descriptor.";
1180-
return llvm::None;
1181-
}
1182-
auto typeNameOffset = (const uint32_t *)typeNameOffsetBytes.get();
1183-
auto typeNameAddress = detail::applyRelativeOffset(
1184-
(const char *)typeNameOffsetAddress, (int32_t)*typeNameOffset);
1185-
std::string typeName;
1186-
OpaqueStringReader(remote::RemoteAddress(typeNameAddress), typeName);
1187-
return typeName;
1188-
}
1189-
1190-
llvm::Optional<std::string> readModuleNameFromModuleDescriptor(
1191-
const ExternalModuleContextDescriptor<ObjCInteropKind, PointerSize>
1192-
*moduleDescriptor,
1193-
uintptr_t moduleDescriptorAddress) {
1194-
auto parentNameOffsetAddress = detail::applyRelativeOffset(
1195-
(const char *)moduleDescriptorAddress,
1196-
(int32_t)moduleDescriptor->getNameOffset());
1197-
auto parentNameOffsetBytes = OpaqueByteReader(
1198-
remote::RemoteAddress(parentNameOffsetAddress), sizeof(uint32_t));
1199-
if (!parentNameOffsetBytes.get()) {
1200-
Error = "Failed to read parent name offset in a module descriptor.";
1201-
return llvm::None;
1202-
}
1203-
auto parentNameOffset = (const uint32_t *)parentNameOffsetBytes.get();
1204-
auto parentNameAddress = detail::applyRelativeOffset(
1205-
(const char *)parentNameOffsetAddress, (int32_t)*parentNameOffset);
1206-
std::string parentName;
1207-
OpaqueStringReader(remote::RemoteAddress(parentNameAddress), parentName);
1208-
return parentName;
1209-
}
1210-
1211-
llvm::Optional<std::string> readAnonymousNameFromAnonymousDescriptor(
1212-
const ExternalAnonymousContextDescriptor<ObjCInteropKind, PointerSize>
1213-
*anonymousDescriptor,
1214-
uintptr_t anonymousDescriptorAddress) {
1215-
if (!anonymousDescriptor->hasMangledName()) {
1216-
std::stringstream stream;
1217-
stream << "(unknown context at $" << std::hex
1218-
<< anonymousDescriptorAddress << ")";
1219-
return stream.str();
1220-
}
1221-
return llvm::None;
1222-
}
1223-
12241283
std::string constructFullyQualifiedNameFromContextChain(
12251284
const std::vector<ContextNameInfo> &contextNameChain) {
12261285
std::string newQualifiedTypeName = "";
@@ -1271,44 +1330,30 @@ class TypeRefBuilder {
12711330

12721331
return newQualifiedTypeName;
12731332
}
1333+
};
12741334

1275-
llvm::Optional<std::string> readProtocolNameFromProtocolDescriptor(
1276-
uintptr_t protocolDescriptorAddress) {
1277-
std::string protocolName;
1278-
auto protocolDescriptorBytes = OpaqueByteReader(
1279-
remote::RemoteAddress(protocolDescriptorAddress),
1280-
sizeof(ExternalProtocolDescriptor<ObjCInteropKind, PointerSize>));
1281-
if (!protocolDescriptorBytes.get()) {
1282-
Error = "Error reading protocol descriptor.";
1283-
return llvm::None;
1284-
}
1285-
const ExternalProtocolDescriptor<ObjCInteropKind, PointerSize>
1286-
*protocolDescriptor =
1287-
(const ExternalProtocolDescriptor<ObjCInteropKind, PointerSize> *)
1288-
protocolDescriptorBytes.get();
1289-
1290-
// Compute the address of the protocol descriptor's name field and read
1291-
// the offset
1292-
auto protocolNameOffsetAddress = detail::applyRelativeOffset(
1293-
(const char *)protocolDescriptorAddress,
1294-
(int32_t)protocolDescriptor->getNameOffset());
1295-
auto protocolNameOffsetBytes = OpaqueByteReader(
1296-
remote::RemoteAddress(protocolNameOffsetAddress), sizeof(uint32_t));
1297-
if (!protocolNameOffsetBytes.get()) {
1298-
Error = "Failed to read type name offset in a protocol descriptor.";
1299-
return llvm::None;
1300-
}
1301-
auto protocolNameOffset = (const uint32_t *)protocolNameOffsetBytes.get();
1335+
///
1336+
/// Extraction of protocol conformances
1337+
///
1338+
private:
1339+
/// Reader of protocol descriptors from Images
1340+
template <template <typename Runtime> class ObjCInteropKind,
1341+
unsigned PointerSize>
1342+
struct ProtocolConformanceDescriptorReader {
1343+
std::string Error;
1344+
PointerReader OpaquePointerReader;
1345+
ByteReader OpaqueByteReader;
1346+
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
1347+
QualifiedContextNameReader<ObjCInteropKind, PointerSize> NameReader;
13021348

1303-
// Using the offset above, compute the address of the name field itsel
1304-
// and read it.
1305-
auto protocolNameAddress =
1306-
detail::applyRelativeOffset((const char *)protocolNameOffsetAddress,
1307-
(int32_t)*protocolNameOffset);
1308-
OpaqueStringReader(remote::RemoteAddress(protocolNameAddress),
1309-
protocolName);
1310-
return protocolName;
1311-
}
1349+
ProtocolConformanceDescriptorReader(ByteReader byteReader,
1350+
StringReader stringReader,
1351+
PointerReader pointerReader,
1352+
DynamicSymbolResolver dynamicSymbolResolver)
1353+
: Error(""),
1354+
OpaquePointerReader(pointerReader), OpaqueByteReader(byteReader),
1355+
OpaqueDynamicSymbolResolver(dynamicSymbolResolver),
1356+
NameReader(byteReader, stringReader, pointerReader, dynamicSymbolResolver) {}
13121357

13131358
/// Extract conforming type's name from a Conformance Descriptor
13141359
/// Returns a pair of (mangledTypeName, fullyQualifiedTypeName)
@@ -1389,7 +1434,7 @@ class TypeRefBuilder {
13891434
return llvm::None;
13901435
}
13911436

1392-
auto optionalTypeName = readTypeNameFromTypeDescriptor(
1437+
auto optionalTypeName = NameReader.readTypeNameFromTypeDescriptor(
13931438
typeDescriptor, contextTypeDescriptorAddress);
13941439
if (!optionalTypeName.hasValue())
13951440
return llvm::None;
@@ -1399,10 +1444,10 @@ class TypeRefBuilder {
13991444
std::vector<ContextNameInfo> contextNameChain;
14001445
contextNameChain.push_back(
14011446
ContextNameInfo{typeName, contextTypeDescriptorAddress, false});
1402-
getParentContextChain(contextTypeDescriptorAddress, contextDescriptor,
1447+
NameReader.getParentContextChain(contextTypeDescriptorAddress, contextDescriptor,
14031448
contextNameChain);
14041449
std::string fullyQualifiedName =
1405-
constructFullyQualifiedNameFromContextChain(contextNameChain);
1450+
NameReader.constructFullyQualifiedNameFromContextChain(contextNameChain);
14061451
return std::make_pair(mangledTypeName, fullyQualifiedName);
14071452
}
14081453

@@ -1435,7 +1480,7 @@ class TypeRefBuilder {
14351480
[&](uintptr_t protocolDescriptorAddress)
14361481
-> llvm::Optional<std::string> {
14371482
auto protocolName =
1438-
readProtocolNameFromProtocolDescriptor(protocolDescriptorAddress);
1483+
NameReader.readProtocolNameFromProtocolDescriptor(protocolDescriptorAddress);
14391484

14401485
// Read the protocol conformance descriptor itself
14411486
auto protocolContextDescriptorBytes = OpaqueByteReader(
@@ -1453,9 +1498,9 @@ class TypeRefBuilder {
14531498
std::vector<ContextNameInfo> contextNameChain;
14541499
contextNameChain.push_back(ContextNameInfo{
14551500
protocolName.getValue(), protocolDescriptorAddress, false});
1456-
getParentContextChain(protocolDescriptorAddress, protocolDescriptor,
1501+
NameReader.getParentContextChain(protocolDescriptorAddress, protocolDescriptor,
14571502
contextNameChain);
1458-
return constructFullyQualifiedNameFromContextChain(contextNameChain);
1503+
return NameReader.constructFullyQualifiedNameFromContextChain(contextNameChain);
14591504
};
14601505

14611506
// Set low bit indicates that this is an indirect

0 commit comments

Comments
 (0)