Skip to content

Commit 1d96037

Browse files
committed
[Static Mirror] Add mangled names to image-extracted protocol conformance infos.
Collect the mapping of unmangled-to-mangled names from the read out `Fields` section reflection infos and use that to identify the mangled name of a conforming type of a given protocol conformance.
1 parent cd6d8f9 commit 1d96037

File tree

2 files changed

+52
-22
lines changed

2 files changed

+52
-22
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,7 @@ struct FieldTypeInfo {
241241
struct ProtocolConformanceInfo {
242242
std::string typeName;
243243
std::string protocolName;
244-
// TODO:
245-
// std::string mangledTypeName;
244+
std::string mangledTypeName;
246245
};
247246

248247
/// An implementation of MetadataReader's BuilderType concept for
@@ -833,16 +832,16 @@ class TypeRefBuilder {
833832
dyn_cast<ExternalModuleContextDescriptor<PointerSize>>(
834833
parentContextDescriptor)) {
835834
auto moduleDescriptorName = readModuleNameFromModuleDescriptor(
836-
moduleDescriptor, parentTargetAddress);
835+
moduleDescriptor, parentTargetAddress);
837836
if (!moduleDescriptorName.hasValue())
838837
return llvm::None;
839838
else
840839
optionalParentName = moduleDescriptorName;
841840
} else if (auto typeDescriptor =
842841
dyn_cast<ExternalTypeContextDescriptor<PointerSize>>(
843842
parentContextDescriptor)) {
844-
auto typeDescriptorName = readTypeNameFromTypeDescriptor(typeDescriptor,
845-
parentTargetAddress);
843+
auto typeDescriptorName = readTypeNameFromTypeDescriptor(
844+
typeDescriptor, parentTargetAddress);
846845
if (!typeDescriptorName.hasValue())
847846
return llvm::None;
848847
else
@@ -1020,10 +1019,10 @@ class TypeRefBuilder {
10201019

10211020
auto optionalTypeName = readTypeNameFromTypeDescriptor(
10221021
typeDescriptor, contextTypeDescriptorAddress);
1023-
if (!optionalTypeName.hasValue())
1024-
return llvm::None;
1025-
else
1026-
typeName = optionalTypeName.getValue();
1022+
if (!optionalTypeName.hasValue())
1023+
return llvm::None;
1024+
else
1025+
typeName = optionalTypeName.getValue();
10271026

10281027
// Prepend the parent context name
10291028
auto optionalParentName =
@@ -1111,7 +1110,9 @@ class TypeRefBuilder {
11111110

11121111
/// Given the address of a conformance descriptor, attempt to read it.
11131112
llvm::Optional<ProtocolConformanceInfo>
1114-
readConformanceDescriptor(RemoteRef<void> conformanceRecordRef) {
1113+
readConformanceDescriptor(RemoteRef<void> conformanceRecordRef,
1114+
const std::unordered_map<std::string, std::string>
1115+
&typeNameToManglingMap) {
11151116
const ExternalProtocolConformanceRecord<PointerSize> *CD =
11161117
(const ExternalProtocolConformanceRecord<PointerSize> *)
11171118
conformanceRecordRef.getLocalBuffer();
@@ -1142,39 +1143,68 @@ class TypeRefBuilder {
11421143
if (!optionalConformanceProtocol.hasValue())
11431144
return llvm::None;
11441145

1146+
std::string mangledTypeName;
1147+
auto it =
1148+
typeNameToManglingMap.find(optionalConformingTypeName.getValue());
1149+
if (it != typeNameToManglingMap.end()) {
1150+
mangledTypeName = it->second;
1151+
} else {
1152+
mangledTypeName = "";
1153+
}
1154+
11451155
return ProtocolConformanceInfo{optionalConformingTypeName.getValue(),
1146-
optionalConformanceProtocol.getValue()};
1156+
optionalConformanceProtocol.getValue(),
1157+
mangledTypeName};
11471158
}
11481159
};
11491160

11501161
public:
11511162
template <unsigned PointerSize>
11521163
void dumpConformanceSection(std::ostream &stream) {
1164+
// The Fields section has gathered info on types that includes their mangled
1165+
// names. Use that to build a dictionary from a type's demangled name to its
1166+
// mangeled name
1167+
std::unordered_map<std::string, std::string> typeNameToManglingMap;
1168+
for (const auto &section : ReflectionInfos) {
1169+
for (auto descriptor : section.Field) {
1170+
auto TypeRef = readTypeRef(descriptor, descriptor->MangledTypeName);
1171+
auto OptionalMangledTypeName = normalizeReflectionName(TypeRef);
1172+
auto TypeName = nodeToString(demangleTypeRef(TypeRef));
1173+
clearNodeFactory();
1174+
if (OptionalMangledTypeName.hasValue()) {
1175+
typeNameToManglingMap[TypeName] =
1176+
"$s" + OptionalMangledTypeName.getValue();
1177+
}
1178+
}
1179+
}
1180+
11531181
// Collect all conformances and aggregate them per-conforming-type.
11541182
std::unordered_map<std::string, std::vector<std::string>> typeConformances;
11551183
ProtocolConformanceDescriptorReader<PointerSize> conformanceReader(
11561184
OpaqueByteReader, OpaqueStringReader, OpaquePointerReader);
1157-
11581185
for (const auto &section : ReflectionInfos) {
11591186
auto ConformanceBegin = section.Conformance.startAddress();
11601187
auto ConformanceEnd = section.Conformance.endAddress();
11611188
for (auto conformanceAddr = ConformanceBegin;
11621189
conformanceAddr != ConformanceEnd;
11631190
conformanceAddr = conformanceAddr.atByteOffset(4)) {
11641191
auto optionalConformanceInfo =
1165-
conformanceReader.readConformanceDescriptor(conformanceAddr);
1192+
conformanceReader.readConformanceDescriptor(conformanceAddr,
1193+
typeNameToManglingMap);
11661194
if (!optionalConformanceInfo.hasValue()) {
11671195
stream << "Error reading conformance descriptor: "
11681196
<< conformanceReader.Error << "\n";
11691197
continue;
11701198
}
11711199
auto conformanceInfo = optionalConformanceInfo.getValue();
1172-
if (typeConformances.count(conformanceInfo.typeName) != 0) {
1173-
typeConformances[conformanceInfo.typeName].push_back(
1200+
auto typeConformancesKey = conformanceInfo.mangledTypeName + " (" +
1201+
conformanceInfo.typeName + ")";
1202+
if (typeConformances.count(typeConformancesKey) != 0) {
1203+
typeConformances[typeConformancesKey].push_back(
11741204
conformanceInfo.protocolName);
11751205
} else {
11761206
typeConformances.emplace(
1177-
conformanceInfo.typeName,
1207+
typeConformancesKey,
11781208
std::vector<std::string>{conformanceInfo.protocolName});
11791209
}
11801210
}

test/Reflection/conformance_descriptors.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
// CHECK: CONFORMANCES:
88
// CHECK: =============
9-
// CHECK-DAG: ConformanceCheck.StructA : ConformanceCheck.MyProto, Swift.Hashable, Swift.Equatable
10-
// CHECK-DAG: ConformanceCheck.C4 : ConformanceCheck.P1, ConformanceCheck.P2
11-
// CHECK-DAG: ConformanceCheck.E4 : ConformanceCheck.P1, ConformanceCheck.P2, ConformanceCheck.P3
12-
// CHECK-DAG: ConformanceCheck.S4 : ConformanceCheck.P1, ConformanceCheck.P2
13-
// CHECK-DAG: ConformanceCheck.foo.bar.baz.qux.quux.corge.grault.garply.waldo.fred.plugh.xyzzy.thud.SomeConformingType : ConformanceCheck.MyProto
14-
// CHECK-DAG: ConformanceCheck.C1 : ConformanceCheck.ClassBoundP
9+
// CHECK-DAG: $s16ConformanceCheck3fooV3barV3bazV3quxV4quuxV5corgeV6graultV6garplyV5waldoV4fredV5plughV5xyzzyV4thudV18SomeConformingTypeV (ConformanceCheck.foo.bar.baz.qux.quux.corge.grault.garply.waldo.fred.plugh.xyzzy.thud.SomeConformingType) : ConformanceCheck.MyProto
10+
// CHECK-DAG: $s16ConformanceCheck7StructAV (ConformanceCheck.StructA) : ConformanceCheck.MyProto, Swift.Hashable, Swift.Equatable
11+
// CHECK-DAG: $s16ConformanceCheck2E4O (ConformanceCheck.E4) : ConformanceCheck.P1, ConformanceCheck.P2, ConformanceCheck.P3
12+
// CHECK-DAG: $s16ConformanceCheck2C4V (ConformanceCheck.C4) : ConformanceCheck.P1, ConformanceCheck.P2
13+
// CHECK-DAG: $s16ConformanceCheck2S4V (ConformanceCheck.S4) : ConformanceCheck.P1, ConformanceCheck.P2
14+
// CHECK-DAG: $s16ConformanceCheck2C1C (ConformanceCheck.C1) : ConformanceCheck.ClassBoundP

0 commit comments

Comments
 (0)