Skip to content

[Static Mirror] Gather local type extension conformance infos correctly #58982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions include/swift/Reflection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,7 @@ class TypeRefBuilder {
using ByteReader = std::function<remote::MemoryReader::ReadBytesResult (remote::RemoteAddress, unsigned)>;
using StringReader = std::function<bool (remote::RemoteAddress, std::string &)>;
using PointerReader = std::function<llvm::Optional<remote::RemoteAbsolutePointer> (remote::RemoteAddress, unsigned)>;
using DynamicSymbolResolver = std::function<llvm::Optional<remote::RemoteAbsolutePointer> (remote::RemoteAddress)>;
using IntVariableReader = std::function<llvm::Optional<uint64_t> (std::string, unsigned)>;

// These fields are captured from the MetadataReader template passed into the
Expand All @@ -868,6 +869,7 @@ class TypeRefBuilder {
ByteReader OpaqueByteReader;
StringReader OpaqueStringReader;
PointerReader OpaquePointerReader;
DynamicSymbolResolver OpaqueDynamicSymbolResolver;
IntVariableReader OpaqueIntVariableReader;

public:
Expand Down Expand Up @@ -895,6 +897,9 @@ class TypeRefBuilder {
OpaquePointerReader([&reader](remote::RemoteAddress address, unsigned size) -> llvm::Optional<remote::RemoteAbsolutePointer> {
return reader.Reader->readPointer(address, size);
}),
OpaqueDynamicSymbolResolver([&reader](remote::RemoteAddress address) -> llvm::Optional<remote::RemoteAbsolutePointer> {
return reader.Reader->getDynamicSymbol(address);
}),
OpaqueIntVariableReader(
[&reader](std::string symbol, unsigned size) -> llvm::Optional<uint64_t> {
llvm::Optional<uint64_t> result;
Expand Down Expand Up @@ -1019,13 +1024,16 @@ class TypeRefBuilder {
ByteReader OpaqueByteReader;
StringReader OpaqueStringReader;
PointerReader OpaquePointerReader;
DynamicSymbolResolver OpaqueDynamicSymbolResolver;

ProtocolConformanceDescriptorReader(ByteReader byteReader,
StringReader stringReader,
PointerReader pointerReader)
PointerReader pointerReader,
DynamicSymbolResolver dynamicSymbolResolver)
: Error(""), OpaqueByteReader(byteReader),
OpaqueStringReader(stringReader), OpaquePointerReader(pointerReader) {
}
OpaqueStringReader(stringReader),
OpaquePointerReader(pointerReader),
OpaqueDynamicSymbolResolver(dynamicSymbolResolver) {}

llvm::Optional<std::string>
getParentContextName(uintptr_t contextDescriptorAddress) {
Expand Down Expand Up @@ -1248,17 +1256,16 @@ class TypeRefBuilder {
return llvm::None;
}
auto contextDescriptorOffset =
(const uint32_t *)contextDescriptorOffsetBytes.get();
(const int32_t *)contextDescriptorOffsetBytes.get();

// Read the type descriptor itself using the address computed above
auto contextTypeDescriptorAddress = detail::applyRelativeOffset(
(const char *)contextDescriptorFieldAddress,
(int32_t)*contextDescriptorOffset);
*contextDescriptorOffset);

// Instead of a type descriptor this may just be a symbol reference, check that first
if (auto symbol = OpaquePointerReader(remote::RemoteAddress(contextTypeDescriptorAddress),
PointerSize)) {
if (!symbol->getSymbol().empty()) {
if (auto symbol = OpaqueDynamicSymbolResolver(remote::RemoteAddress(contextTypeDescriptorAddress))) {
if (!symbol->isResolved()) {
mangledTypeName = symbol->getSymbol().str();
Demangle::Context Ctx;
auto demangledRoot =
Expand All @@ -1267,6 +1274,9 @@ class TypeRefBuilder {
typeName =
nodeToString(demangledRoot->getChild(0)->getChild(0));
return std::make_pair(mangledTypeName, typeName);
} else if (symbol->getOffset()) {
// If symbol is empty and has an offset, this is the resolved remote address
contextTypeDescriptorAddress = symbol->getOffset();
}
}

Expand Down Expand Up @@ -1462,7 +1472,7 @@ class TypeRefBuilder {
std::unordered_map<std::string, std::vector<std::string>> typeConformances;
ProtocolConformanceDescriptorReader<ObjCInteropKind, PointerSize>
conformanceReader(OpaqueByteReader, OpaqueStringReader,
OpaquePointerReader);
OpaquePointerReader, OpaqueDynamicSymbolResolver);
for (const auto &section : ReflectionInfos) {
auto ConformanceBegin = section.Conformance.startAddress();
auto ConformanceEnd = section.Conformance.endAddress();
Expand Down
2 changes: 2 additions & 0 deletions test/Reflection/Inputs/Conformances.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ struct foo {
}
}
}

extension foo : MyProto {}
1 change: 1 addition & 0 deletions test/Reflection/conformance_descriptors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
// CHECK-DAG: 16ConformanceCheck2C4V (ConformanceCheck.C4) : ConformanceCheck.P1, ConformanceCheck.P2
// CHECK-DAG: 16ConformanceCheck2S4V (ConformanceCheck.S4) : ConformanceCheck.P1, ConformanceCheck.P2
// CHECK-DAG: 16ConformanceCheck2C1C (ConformanceCheck.C1) : ConformanceCheck.ClassBoundP
// CHECK-DAG: 16ConformanceCheck3fooV (ConformanceCheck.foo) : ConformanceCheck.MyProto