Skip to content

Commit b680591

Browse files
committed
Factor out gathering of context names into a separate reader type inside 'TypeRefBuilder'
1 parent 4a74c1a commit b680591

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
@@ -1005,9 +1005,8 @@ class TypeRefBuilder {
10051005
}
10061006

10071007
///
1008-
/// Dumping typerefs, field declarations, associated types
1008+
/// Dumping typerefs, field declarations, builtin types, captures, multi-payload enums
10091009
///
1010-
10111010
void dumpTypeRef(RemoteRef<char> MangledName, std::ostream &stream,
10121011
bool printTypeName = false);
10131012
FieldTypeCollectionResult collectFieldTypes(llvm::Optional<std::string> forMangledTypeName);
@@ -1018,43 +1017,151 @@ class TypeRefBuilder {
10181017
void dumpCaptureSection(std::ostream &stream);
10191018
void dumpMultiPayloadEnumSection(std::ostream &stream);
10201019

1021-
///
1022-
/// Extraction of protocol conformances
1023-
///
1024-
10251020
private:
1026-
/// Reader of protocol descriptors from Images
1021+
struct ContextNameInfo {
1022+
std::string name;
1023+
uintptr_t descriptorAddress;
1024+
bool isAnonymous;
1025+
1026+
~ContextNameInfo() {}
1027+
};
1028+
10271029
template <template <typename Runtime> class ObjCInteropKind,
10281030
unsigned PointerSize>
1029-
struct ProtocolConformanceDescriptorReader {
1031+
struct QualifiedContextNameReader {
10301032
std::string Error;
10311033
ByteReader OpaqueByteReader;
10321034
StringReader OpaqueStringReader;
10331035
PointerReader OpaquePointerReader;
10341036
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
10351037

1036-
ProtocolConformanceDescriptorReader(ByteReader byteReader,
1037-
StringReader stringReader,
1038-
PointerReader pointerReader,
1039-
DynamicSymbolResolver dynamicSymbolResolver)
1038+
QualifiedContextNameReader(ByteReader byteReader,
1039+
StringReader stringReader,
1040+
PointerReader pointerReader,
1041+
DynamicSymbolResolver dynamicSymbolResolver)
10401042
: Error(""), OpaqueByteReader(byteReader),
10411043
OpaqueStringReader(stringReader),
10421044
OpaquePointerReader(pointerReader),
10431045
OpaqueDynamicSymbolResolver(dynamicSymbolResolver) {}
10441046

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

1050-
~ContextNameInfo() {}
1051-
};
1062+
// Compute the address of the protocol descriptor's name field and read
1063+
// the offset
1064+
auto protocolNameOffsetAddress = detail::applyRelativeOffset(
1065+
(const char *)protocolDescriptorAddress,
1066+
(int32_t)protocolDescriptor->getNameOffset());
1067+
auto protocolNameOffsetBytes = OpaqueByteReader(
1068+
remote::RemoteAddress(protocolNameOffsetAddress), sizeof(uint32_t));
1069+
if (!protocolNameOffsetBytes.get()) {
1070+
Error = "Failed to read type name offset in a protocol descriptor.";
1071+
return llvm::None;
1072+
}
1073+
auto protocolNameOffset = (const uint32_t *)protocolNameOffsetBytes.get();
10521074

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

10601167
uintptr_t getParentDescriptorAddress(
@@ -1111,6 +1218,13 @@ class TypeRefBuilder {
11111218
}
11121219
}
11131220

1221+
bool isModuleDescriptor(
1222+
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
1223+
*contextDescriptor) {
1224+
return isa<ExternalModuleContextDescriptor<ObjCInteropKind, PointerSize>>(
1225+
contextDescriptor);
1226+
}
1227+
11141228
void getParentContextChain(
11151229
uintptr_t contextDescriptorAddress,
11161230
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
@@ -1172,61 +1286,6 @@ class TypeRefBuilder {
11721286
return;
11731287
}
11741288

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

12781337
return newQualifiedTypeName;
12791338
}
1339+
};
12801340

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

1309-
// Using the offset above, compute the address of the name field itsel
1310-
// and read it.
1311-
auto protocolNameAddress =
1312-
detail::applyRelativeOffset((const char *)protocolNameOffsetAddress,
1313-
(int32_t)*protocolNameOffset);
1314-
OpaqueStringReader(remote::RemoteAddress(protocolNameAddress),
1315-
protocolName);
1316-
return protocolName;
1317-
}
1355+
ProtocolConformanceDescriptorReader(ByteReader byteReader,
1356+
StringReader stringReader,
1357+
PointerReader pointerReader,
1358+
DynamicSymbolResolver dynamicSymbolResolver)
1359+
: Error(""),
1360+
OpaquePointerReader(pointerReader), OpaqueByteReader(byteReader),
1361+
OpaqueDynamicSymbolResolver(dynamicSymbolResolver),
1362+
NameReader(byteReader, stringReader, pointerReader, dynamicSymbolResolver) {}
13181363

13191364
/// Extract conforming type's name from a Conformance Descriptor
13201365
/// Returns a pair of (mangledTypeName, fullyQualifiedTypeName)
@@ -1403,7 +1448,7 @@ class TypeRefBuilder {
14031448
return llvm::None;
14041449
}
14051450

1406-
auto optionalTypeName = readTypeNameFromTypeDescriptor(
1451+
auto optionalTypeName = NameReader.readTypeNameFromTypeDescriptor(
14071452
typeDescriptor, contextTypeDescriptorAddress);
14081453
if (!optionalTypeName.hasValue())
14091454
return llvm::None;
@@ -1413,10 +1458,10 @@ class TypeRefBuilder {
14131458
std::vector<ContextNameInfo> contextNameChain;
14141459
contextNameChain.push_back(
14151460
ContextNameInfo{typeName, contextTypeDescriptorAddress, false});
1416-
getParentContextChain(contextTypeDescriptorAddress, contextDescriptor,
1461+
NameReader.getParentContextChain(contextTypeDescriptorAddress, contextDescriptor,
14171462
contextNameChain);
14181463
std::string fullyQualifiedName =
1419-
constructFullyQualifiedNameFromContextChain(contextNameChain);
1464+
NameReader.constructFullyQualifiedNameFromContextChain(contextNameChain);
14201465
return std::make_pair(mangledTypeName, fullyQualifiedName);
14211466
}
14221467

@@ -1449,7 +1494,7 @@ class TypeRefBuilder {
14491494
[&](uintptr_t protocolDescriptorAddress)
14501495
-> llvm::Optional<std::string> {
14511496
auto protocolName =
1452-
readProtocolNameFromProtocolDescriptor(protocolDescriptorAddress);
1497+
NameReader.readProtocolNameFromProtocolDescriptor(protocolDescriptorAddress);
14531498

14541499
// Read the protocol conformance descriptor itself
14551500
auto protocolContextDescriptorBytes = OpaqueByteReader(
@@ -1467,9 +1512,9 @@ class TypeRefBuilder {
14671512
std::vector<ContextNameInfo> contextNameChain;
14681513
contextNameChain.push_back(ContextNameInfo{
14691514
protocolName.getValue(), protocolDescriptorAddress, false});
1470-
getParentContextChain(protocolDescriptorAddress, protocolDescriptor,
1515+
NameReader.getParentContextChain(protocolDescriptorAddress, protocolDescriptor,
14711516
contextNameChain);
1472-
return constructFullyQualifiedNameFromContextChain(contextNameChain);
1517+
return NameReader.constructFullyQualifiedNameFromContextChain(contextNameChain);
14731518
};
14741519

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

0 commit comments

Comments
 (0)