Skip to content

Commit ea0899d

Browse files
committed
Common-out protocol name and type name reading code into the 'QualifiedContextNameReader'.
1 parent 92011f2 commit ea0899d

File tree

2 files changed

+91
-99
lines changed

2 files changed

+91
-99
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 87 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,86 @@ class TypeRefBuilder {
12351235
return llvm::None;
12361236
}
12371237

1238+
llvm::Optional<std::string>
1239+
readFullyQualifiedTypeName(uintptr_t typeDescriptorTarget) {
1240+
std::string typeName;
1241+
auto contextTypeDescriptorBytes = OpaqueByteReader(
1242+
remote::RemoteAddress(typeDescriptorTarget),
1243+
sizeof(ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
1244+
if (!contextTypeDescriptorBytes.get()) {
1245+
Error = "Failed to read context descriptor.";
1246+
return llvm::None;
1247+
}
1248+
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
1249+
*contextDescriptor =
1250+
(const ExternalContextDescriptor<ObjCInteropKind, PointerSize> *)
1251+
contextTypeDescriptorBytes.get();
1252+
1253+
auto typeDescriptor =
1254+
dyn_cast<ExternalTypeContextDescriptor<ObjCInteropKind, PointerSize>>(
1255+
contextDescriptor);
1256+
if (!typeDescriptor) {
1257+
Error = "Unexpected type of context descriptor.";
1258+
return llvm::None;
1259+
}
1260+
1261+
auto optionalTypeName = readTypeNameFromTypeDescriptor(
1262+
typeDescriptor, typeDescriptorTarget);
1263+
if (!optionalTypeName.hasValue())
1264+
return llvm::None;
1265+
else
1266+
typeName = optionalTypeName.getValue();
1267+
1268+
std::vector<ContextNameInfo> contextNameChain;
1269+
contextNameChain.push_back(
1270+
ContextNameInfo{typeName, typeDescriptorTarget, false});
1271+
getParentContextChain(typeDescriptorTarget, contextDescriptor,
1272+
contextNameChain);
1273+
return constructFullyQualifiedNameFromContextChain(contextNameChain);
1274+
}
1275+
1276+
llvm::Optional<std::string>
1277+
readFullyQualifiedProtocolName(
1278+
uintptr_t protocolDescriptorTarget) {
1279+
llvm::Optional<std::string> protocolName;
1280+
// Set low bit indicates that this is an indirect
1281+
// reference
1282+
if (protocolDescriptorTarget & 0x1) {
1283+
auto adjustedProtocolDescriptorTarget = protocolDescriptorTarget & ~0x1;
1284+
if (auto symbol = OpaquePointerReader(
1285+
remote::RemoteAddress(adjustedProtocolDescriptorTarget),
1286+
PointerSize)) {
1287+
if (!symbol->getSymbol().empty()) {
1288+
Demangle::Context Ctx;
1289+
auto demangledRoot =
1290+
Ctx.demangleSymbolAsNode(symbol->getSymbol().str());
1291+
assert(demangledRoot->getKind() == Node::Kind::Global);
1292+
assert(demangledRoot->getChild(0)->getKind() ==
1293+
Node::Kind::ProtocolDescriptor);
1294+
protocolName =
1295+
nodeToString(demangledRoot->getChild(0)->getChild(0));
1296+
} else {
1297+
// This is an absolute address of a protocol descriptor
1298+
auto protocolDescriptorAddress = (uintptr_t)symbol->getOffset();
1299+
protocolName =
1300+
readFullyQualifiedProtocolNameFromProtocolDescriptor(
1301+
protocolDescriptorAddress);
1302+
}
1303+
} else {
1304+
Error = "Error reading external protocol address.";
1305+
return llvm::None;
1306+
}
1307+
} else {
1308+
// If this is a direct reference, get symbol name from the protocol
1309+
// descriptor.
1310+
protocolName =
1311+
readFullyQualifiedProtocolNameFromProtocolDescriptor(
1312+
protocolDescriptorTarget);
1313+
}
1314+
return protocolName;
1315+
}
1316+
1317+
private:
12381318
llvm::Optional<std::string>
12391319
readFullyQualifiedProtocolNameFromProtocolDescriptor(
12401320
uintptr_t protocolDescriptorAddress) {
@@ -1504,7 +1584,7 @@ class TypeRefBuilder {
15041584
OpaqueByteReader, OpaqueStringReader, OpaquePointerReader,
15051585
OpaqueDynamicSymbolResolver);
15061586
auto conformanceRequirementProtocolName =
1507-
nameReader.readFullyQualifiedProtocolNameFromProtocolDescriptor(
1587+
nameReader.readFullyQualifiedProtocolName(
15081588
protocolDescriptorAddress);
15091589
result.push_back(*conformanceRequirementProtocolName);
15101590
}
@@ -1594,41 +1674,12 @@ class TypeRefBuilder {
15941674
}
15951675
}
15961676

1597-
auto contextTypeDescriptorBytes = OpaqueByteReader(
1598-
remote::RemoteAddress(contextTypeDescriptorAddress),
1599-
sizeof(ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
1600-
if (!contextTypeDescriptorBytes.get()) {
1601-
Error = "Failed to read context descriptor.";
1602-
return llvm::None;
1603-
}
1604-
const ExternalContextDescriptor<ObjCInteropKind, PointerSize>
1605-
*contextDescriptor =
1606-
(const ExternalContextDescriptor<ObjCInteropKind, PointerSize> *)
1607-
contextTypeDescriptorBytes.get();
1608-
1609-
auto typeDescriptor =
1610-
dyn_cast<ExternalTypeContextDescriptor<ObjCInteropKind, PointerSize>>(
1611-
contextDescriptor);
1612-
if (!typeDescriptor) {
1613-
Error = "Unexpected type of context descriptor.";
1614-
return llvm::None;
1615-
}
1616-
1617-
auto optionalTypeName = NameReader.readTypeNameFromTypeDescriptor(
1618-
typeDescriptor, contextTypeDescriptorAddress);
1619-
if (!optionalTypeName.hasValue())
1677+
auto fullyQualifiedName =
1678+
NameReader.readFullyQualifiedTypeName(contextTypeDescriptorAddress);
1679+
if (!fullyQualifiedName.hasValue())
16201680
return llvm::None;
16211681
else
1622-
typeName = optionalTypeName.getValue();
1623-
1624-
std::vector<ContextNameInfo> contextNameChain;
1625-
contextNameChain.push_back(
1626-
ContextNameInfo{typeName, contextTypeDescriptorAddress, false});
1627-
NameReader.getParentContextChain(contextTypeDescriptorAddress, contextDescriptor,
1628-
contextNameChain);
1629-
std::string fullyQualifiedName =
1630-
NameReader.constructFullyQualifiedNameFromContextChain(contextNameChain);
1631-
return std::make_pair(mangledTypeName, fullyQualifiedName);
1682+
return std::make_pair(mangledTypeName, *fullyQualifiedName);
16321683
}
16331684

16341685
/// Extract protocol name from a Conformance Descriptor
@@ -1656,67 +1707,8 @@ class TypeRefBuilder {
16561707
(const char *)protocolDescriptorFieldAddress,
16571708
(int32_t)*protocolDescriptorOffset);
16581709

1659-
auto constructFullyQualifiedProtocolName =
1660-
[&](uintptr_t protocolDescriptorAddress)
1661-
-> llvm::Optional<std::string> {
1662-
auto protocolName =
1663-
NameReader.readProtocolNameFromProtocolDescriptor(protocolDescriptorAddress);
1664-
1665-
// Read the protocol conformance descriptor itself
1666-
auto protocolContextDescriptorBytes = OpaqueByteReader(
1667-
remote::RemoteAddress(protocolDescriptorAddress),
1668-
sizeof(ExternalContextDescriptor<ObjCInteropKind, PointerSize>));
1669-
if (!protocolContextDescriptorBytes.get()) {
1670-
Error = "Failed to read context (protocol) descriptor.";
1671-
return llvm::None;
1672-
}
1673-
const ExternalContextDescriptor<ObjCInteropKind,
1674-
PointerSize> *protocolDescriptor =
1675-
(const ExternalContextDescriptor<ObjCInteropKind, PointerSize> *)
1676-
protocolContextDescriptorBytes.get();
1677-
1678-
std::vector<ContextNameInfo> contextNameChain;
1679-
contextNameChain.push_back(ContextNameInfo{
1680-
protocolName.getValue(), protocolDescriptorAddress, false});
1681-
NameReader.getParentContextChain(protocolDescriptorAddress, protocolDescriptor,
1682-
contextNameChain);
1683-
return NameReader.constructFullyQualifiedNameFromContextChain(contextNameChain);
1684-
};
1685-
1686-
// Set low bit indicates that this is an indirect
1687-
// reference
1688-
if (protocolDescriptorTarget & 0x1) {
1689-
auto adjustedProtocolDescriptorTarget = protocolDescriptorTarget & ~0x1;
1690-
if (auto symbol = OpaquePointerReader(
1691-
remote::RemoteAddress(adjustedProtocolDescriptorTarget),
1692-
PointerSize)) {
1693-
if (!symbol->getSymbol().empty()) {
1694-
Demangle::Context Ctx;
1695-
auto demangledRoot =
1696-
Ctx.demangleSymbolAsNode(symbol->getSymbol().str());
1697-
assert(demangledRoot->getKind() == Node::Kind::Global);
1698-
assert(demangledRoot->getChild(0)->getKind() ==
1699-
Node::Kind::ProtocolDescriptor);
1700-
protocolName =
1701-
nodeToString(demangledRoot->getChild(0)->getChild(0));
1702-
} else {
1703-
// This is an absolute address of a protocol descriptor
1704-
auto protocolDescriptorAddress = (uintptr_t)symbol->getOffset();
1705-
protocolName =
1706-
constructFullyQualifiedProtocolName(protocolDescriptorAddress);
1707-
}
1708-
} else {
1709-
Error = "Error reading external protocol address.";
1710-
return llvm::None;
1711-
}
1712-
} else {
1713-
// If this is a direct reference, get symbol name from the protocol
1714-
// descriptor.
1715-
protocolName =
1716-
constructFullyQualifiedProtocolName(protocolDescriptorTarget);
1717-
}
1718-
1719-
return protocolName;
1710+
return NameReader.readFullyQualifiedProtocolName(
1711+
protocolDescriptorTarget);
17201712
}
17211713

17221714
/// Given the address of a conformance descriptor, attempt to read it.

test/Reflection/opaque_associated_type_requirements.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
// RUN: %target-build-swift %s -parse-as-library -target %target-cpu-apple-macosx10.15 -I %t/includes -emit-module -emit-library -module-name AssociatedTypeRequirements -o %t/AssociatedTypeRequirements %t/includes/testModB.o
99

10-
// RUN: %target-swift-reflection-dump -binary-filename %t/AssociatedTypeRequirements -binary-filename %platform-module-dir/%target-library-name(swiftCore) | %FileCheck %s
10+
// RUN: %target-swift-reflection-dump -binary-filename %t/AssociatedTypeRequirements | %FileCheck %s
1111

1212
// CHECK: ASSOCIATED TYPES:
1313
// CHECK-NEXT: =============
@@ -17,9 +17,9 @@
1717
// CHECK-NEXT: (struct AssociatedTypeRequirements.Bar)
1818

1919
// CHECK: opaque type conformance requirements:
20-
// CHECK-DAG: AssociatedTypeRequirements.protoA
21-
// CHECK-DAG: AssociatedTypeRequirements.protoB
22-
// CHECK-DAG: testModB.testModBProtocol
20+
// CHECK-NEXT: AssociatedTypeRequirements.protoA
21+
// CHECK-NEXT: AssociatedTypeRequirements.protoB
22+
// CHECK-NEXT: testModB.testModBProtocol
2323

2424
import testModB
2525

0 commit comments

Comments
 (0)