Add a callback to swift::reflection::MemoryReader that allows LLDB to provide

swift::reflection::TypeInfo for (Clang-)imported non-Objective-C types. This is
needed to reflect on the size mixed Swift / Clang types, when no type metadata
is available for the C types.

This is a necessary ingredient for the TypeRef-based Swift context in
LLDB. Because we do not have reflection metadata for pure C types in Swift,
reflection cannot compute TypeInfo for NominalTypeRefs for those types. By
providing this callback, LLDB can supply this information for DWARF, and
reflection can compute TypeInfos for mixed Swift/C types.
This commit is contained in:
Adrian Prantl
2020-08-11 17:41:19 -07:00
parent 45be7f2192
commit 4b9cf31ba0
12 changed files with 185 additions and 114 deletions

View File

@@ -328,9 +328,8 @@ class TypeDecoder {
BuilderType &Builder;
public:
explicit TypeDecoder(BuilderType &Builder)
: Builder(Builder) {}
public:
explicit TypeDecoder(BuilderType &Builder) : Builder(Builder) {}
/// Given a demangle tree, attempt to turn it into a type.
BuiltType decodeMangledType(NodePointer Node) {

View File

@@ -680,7 +680,9 @@ public:
/// Return a description of the layout of a class instance with the given
/// metadata as its isa pointer.
const TypeInfo *getMetadataTypeInfo(StoredPointer MetadataAddress) {
const TypeInfo *
getMetadataTypeInfo(StoredPointer MetadataAddress,
remote::TypeInfoProvider *ExternalTypeInfo) {
// See if we cached the layout already
auto found = Cache.find(MetadataAddress);
if (found != Cache.end())
@@ -702,7 +704,7 @@ public:
// Perform layout
if (start)
TI = TC.getClassInstanceTypeInfo(TR, *start);
TI = TC.getClassInstanceTypeInfo(TR, *start, ExternalTypeInfo);
break;
}
@@ -718,7 +720,9 @@ public:
/// Return a description of the layout of a class instance with the given
/// metadata as its isa pointer.
const TypeInfo *getInstanceTypeInfo(StoredPointer ObjectAddress) {
const TypeInfo *
getInstanceTypeInfo(StoredPointer ObjectAddress,
remote::TypeInfoProvider *ExternalTypeInfo) {
auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
if (!MetadataAddress)
return nullptr;
@@ -729,7 +733,7 @@ public:
switch (*kind) {
case MetadataKind::Class:
return getMetadataTypeInfo(*MetadataAddress);
return getMetadataTypeInfo(*MetadataAddress, ExternalTypeInfo);
case MetadataKind::HeapLocalVariable: {
auto CDAddr = this->readCaptureDescriptorFromMetadata(*MetadataAddress);
@@ -751,7 +755,7 @@ public:
auto Info = getBuilder().getClosureContextInfo(CD);
return getClosureContextInfo(ObjectAddress, Info);
return getClosureContextInfo(ObjectAddress, Info, ExternalTypeInfo);
}
case MetadataKind::HeapGenericLocalVariable: {
@@ -760,7 +764,8 @@ public:
if (auto Meta = readMetadata(*MetadataAddress)) {
auto GenericHeapMeta =
cast<TargetGenericBoxHeapMetadata<Runtime>>(Meta.getLocalBuffer());
return getMetadataTypeInfo(GenericHeapMeta->BoxedType);
return getMetadataTypeInfo(GenericHeapMeta->BoxedType,
ExternalTypeInfo);
}
return nullptr;
}
@@ -774,15 +779,15 @@ public:
}
}
bool
projectExistential(RemoteAddress ExistentialAddress,
const TypeRef *ExistentialTR,
const TypeRef **OutInstanceTR,
RemoteAddress *OutInstanceAddress) {
bool projectExistential(RemoteAddress ExistentialAddress,
const TypeRef *ExistentialTR,
const TypeRef **OutInstanceTR,
RemoteAddress *OutInstanceAddress,
remote::TypeInfoProvider *ExternalTypeInfo) {
if (ExistentialTR == nullptr)
return false;
auto ExistentialTI = getTypeInfo(ExistentialTR);
auto ExistentialTI = getTypeInfo(ExistentialTR, ExternalTypeInfo);
if (ExistentialTI == nullptr)
return false;
@@ -846,14 +851,14 @@ public:
/// Returns true if the enum case could be successfully determined. In
/// particular, note that this code may return false for valid in-memory data
/// if the compiler used a strategy we do not yet understand.
bool projectEnumValue(RemoteAddress EnumAddress,
const TypeRef *EnumTR,
int *CaseIndex) {
bool projectEnumValue(RemoteAddress EnumAddress, const TypeRef *EnumTR,
int *CaseIndex,
remote::TypeInfoProvider *ExternalTypeInfo) {
// Get the TypeInfo and sanity-check it
if (EnumTR == nullptr) {
return false;
}
auto TI = getTypeInfo(EnumTR);
auto TI = getTypeInfo(EnumTR, ExternalTypeInfo);
if (TI == nullptr) {
return false;
}
@@ -865,11 +870,12 @@ public:
}
/// Return a description of the layout of a value with the given type.
const TypeInfo *getTypeInfo(const TypeRef *TR) {
const TypeInfo *getTypeInfo(const TypeRef *TR,
remote::TypeInfoProvider *ExternalTypeInfo) {
if (TR == nullptr) {
return nullptr;
} else {
return getBuilder().getTypeConverter().getTypeInfo(TR);
return getBuilder().getTypeConverter().getTypeInfo(TR, ExternalTypeInfo);
}
}
@@ -1160,8 +1166,9 @@ public:
}
private:
const TypeInfo *getClosureContextInfo(StoredPointer Context,
const ClosureContextInfo &Info) {
const TypeInfo *
getClosureContextInfo(StoredPointer Context, const ClosureContextInfo &Info,
remote::TypeInfoProvider *ExternalTypeInfo) {
RecordTypeInfoBuilder Builder(getBuilder().getTypeConverter(),
RecordKind::ClosureContext);
@@ -1219,7 +1226,7 @@ private:
SubstCaptureTR = OrigCaptureTR;
if (SubstCaptureTR != nullptr) {
Builder.addField("", SubstCaptureTR);
Builder.addField("", SubstCaptureTR, ExternalTypeInfo);
if (Builder.isInvalid())
return nullptr;

View File

@@ -22,6 +22,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Casting.h"
#include "swift/Remote/MetadataReader.h"
#include "swift/Remote/TypeInfoProvider.h"
#include <memory>
@@ -347,14 +348,16 @@ public:
///
/// The type must either be concrete, or at least fixed-size, as
/// determined by the isFixedSize() predicate.
const TypeInfo *getTypeInfo(const TypeRef *TR);
const TypeInfo *getTypeInfo(const TypeRef *TR,
remote::TypeInfoProvider *externalInfo);
/// Returns layout information for an instance of the given
/// class.
///
/// Not cached.
const TypeInfo *getClassInstanceTypeInfo(const TypeRef *TR,
unsigned start);
const TypeInfo *
getClassInstanceTypeInfo(const TypeRef *TR, unsigned start,
remote::TypeInfoProvider *ExternalTypeInfo);
private:
friend class swift::reflection::LowerType;
@@ -415,7 +418,8 @@ public:
bool bitwiseTakable);
// Add a field of a record type, such as a struct.
void addField(const std::string &Name, const TypeRef *TR);
void addField(const std::string &Name, const TypeRef *TR,
remote::TypeInfoProvider *ExternalTypeInfo);
const RecordTypeInfo *build();

View File

@@ -156,8 +156,8 @@ public:
bool isConcrete() const;
bool isConcreteAfterSubstitutions(const GenericArgumentMap &Subs) const;
const TypeRef *
subst(TypeRefBuilder &Builder, const GenericArgumentMap &Subs) const;
const TypeRef *subst(TypeRefBuilder &Builder,
const GenericArgumentMap &Subs) const;
llvm::Optional<GenericArgumentMap> getSubstMap() const;

View File

@@ -634,16 +634,14 @@ public:
const std::string &Member,
StringRef Protocol);
const TypeRef *
lookupSuperclass(const TypeRef *TR);
const TypeRef *lookupSuperclass(const TypeRef *TR);
/// Load unsubstituted field types for a nominal type.
RemoteRef<FieldDescriptor>
getFieldTypeInfo(const TypeRef *TR);
RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
/// Get the parsed and substituted field types for a nominal type.
bool getFieldTypeRefs(const TypeRef *TR,
RemoteRef<FieldDescriptor> FD,
bool getFieldTypeRefs(const TypeRef *TR, RemoteRef<FieldDescriptor> FD,
remote::TypeInfoProvider *ExternalTypeInfo,
std::vector<FieldTypeInfo> &Fields);
/// Get the primitive type lowering for a builtin type.

View File

@@ -37,7 +37,8 @@ namespace remote {
class MemoryReader {
public:
/// A convenient name for the return type from readBytes.
using ReadBytesResult = std::unique_ptr<const void, std::function<void(const void *)>>;
using ReadBytesResult =
std::unique_ptr<const void, std::function<void(const void *)>>;
virtual bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
void *outBuffer) = 0;
@@ -152,9 +153,8 @@ public:
return resolvePointer(address, pointerData);
}
// Parse extra inhabitants stored in a pointer.
// Parse extra inhabitants stored in a pointer.
// Sets *extraInhabitant to -1 if the pointer at this address
// is actually a valid pointer.
// Otherwise, it sets *extraInhabitant to the inhabitant

View File

@@ -0,0 +1,39 @@
//===--- TypeInfoProvider.h - Abstract access to type info ------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file declares an abstract interface for reading type layout info.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_REMOTE_TYPEINFOPROVIDER_H
#define SWIFT_REMOTE_TYPEINFOPROVIDER_H
namespace swift {
namespace reflection {
class TypeInfo;
}
namespace remote {
/// An abstract interface for providing external type layout information.
struct TypeInfoProvider {
virtual ~TypeInfoProvider() = default;
/// Attempt to read type information about (Clang)imported types that are not
/// represented in the metadata. LLDB can read this information from debug
/// info, for example.
virtual const reflection::TypeInfo *
getTypeInfo(llvm::StringRef mangledName) = 0;
};
} // namespace remote
} // namespace swift
#endif

View File

@@ -1034,7 +1034,10 @@ class ExistentialTypeInfoBuilder {
++WitnessTableCount;
if (auto *Superclass = TC.getBuilder().lookupSuperclass(P)) {
auto *SuperclassTI = TC.getTypeInfo(Superclass);
// ObjC class info should be available in the metadata, so it's safe
// to not pass an external provider here. This helps preserving the
// layering.
auto *SuperclassTI = TC.getTypeInfo(Superclass, nullptr);
if (SuperclassTI == nullptr) {
DEBUG_LOG(fprintf(stderr, "No TypeInfo for superclass: ");
Superclass->dump());
@@ -1140,7 +1143,7 @@ public:
Invalid = true;
}
const TypeInfo *build() {
const TypeInfo *build(remote::TypeInfoProvider *ExternalTypeInfo) {
examineProtocols();
if (Invalid)
@@ -1176,12 +1179,14 @@ public:
// Class existentials consist of a single retainable pointer
// followed by witness tables.
if (Refcounting == ReferenceCounting::Unknown)
builder.addField("object", TC.getUnknownObjectTypeRef());
builder.addField("object", TC.getUnknownObjectTypeRef(),
ExternalTypeInfo);
else
builder.addField("object", TC.getNativeObjectTypeRef());
builder.addField("object", TC.getNativeObjectTypeRef(),
ExternalTypeInfo);
break;
case ExistentialTypeRepresentation::Opaque: {
auto *TI = TC.getTypeInfo(TC.getRawPointerTypeRef());
auto *TI = TC.getTypeInfo(TC.getRawPointerTypeRef(), ExternalTypeInfo);
if (TI == nullptr) {
DEBUG_LOG(fprintf(stderr, "No TypeInfo for RawPointer\n"));
return nullptr;
@@ -1195,21 +1200,21 @@ public:
TI->getAlignment(),
/*numExtraInhabitants=*/0,
/*bitwiseTakable=*/true);
builder.addField("metadata", TC.getAnyMetatypeTypeRef());
builder.addField("metadata", TC.getAnyMetatypeTypeRef(), ExternalTypeInfo);
break;
}
case ExistentialTypeRepresentation::Error:
builder.addField("error", TC.getUnknownObjectTypeRef());
builder.addField("error", TC.getUnknownObjectTypeRef(), ExternalTypeInfo);
break;
}
for (unsigned i = 0; i < WitnessTableCount; ++i)
builder.addField("wtable", TC.getRawPointerTypeRef());
builder.addField("wtable", TC.getRawPointerTypeRef(), ExternalTypeInfo);
return builder.build();
}
const TypeInfo *buildMetatype() {
const TypeInfo *buildMetatype(remote::TypeInfoProvider *ExternalTypeInfo) {
examineProtocols();
if (Invalid)
@@ -1226,9 +1231,9 @@ public:
RecordTypeInfoBuilder builder(TC, RecordKind::ExistentialMetatype);
builder.addField("metadata", TC.getAnyMetatypeTypeRef());
builder.addField("metadata", TC.getAnyMetatypeTypeRef(), ExternalTypeInfo);
for (unsigned i = 0; i < WitnessTableCount; ++i)
builder.addField("wtable", TC.getRawPointerTypeRef());
builder.addField("wtable", TC.getRawPointerTypeRef(), ExternalTypeInfo);
return builder.build();
}
@@ -1285,9 +1290,10 @@ unsigned RecordTypeInfoBuilder::addField(unsigned fieldSize,
return offset;
}
void RecordTypeInfoBuilder::addField(const std::string &Name,
const TypeRef *TR) {
const TypeInfo *TI = TC.getTypeInfo(TR);
void RecordTypeInfoBuilder::addField(
const std::string &Name, const TypeRef *TR,
remote::TypeInfoProvider *ExternalTypeInfo) {
const TypeInfo *TI = TC.getTypeInfo(TR, ExternalTypeInfo);
if (TI == nullptr) {
DEBUG_LOG(fprintf(stderr, "No TypeInfo for field type: "); TR->dump());
Invalid = true;
@@ -1394,14 +1400,13 @@ TypeConverter::getThinFunctionTypeInfo() {
/// Thick functions consist of a function pointer and nullable retainable
/// context pointer. The context is modeled exactly like a native Swift
/// class reference.
const TypeInfo *
TypeConverter::getThickFunctionTypeInfo() {
const TypeInfo *TypeConverter::getThickFunctionTypeInfo() {
if (ThickFunctionTI != nullptr)
return ThickFunctionTI;
RecordTypeInfoBuilder builder(*this, RecordKind::ThickFunction);
builder.addField("function", getThinFunctionTypeRef());
builder.addField("context", getNativeObjectTypeRef());
builder.addField("function", getThinFunctionTypeRef(), nullptr);
builder.addField("context", getNativeObjectTypeRef(), nullptr);
ThickFunctionTI = builder.build();
return ThickFunctionTI;
@@ -1758,14 +1763,14 @@ public:
: TC(TC), Size(0), Alignment(1), NumExtraInhabitants(0),
BitwiseTakable(true), Invalid(false) {}
const TypeInfo *
build(const TypeRef *TR, RemoteRef<FieldDescriptor> FD) {
const TypeInfo *build(const TypeRef *TR, RemoteRef<FieldDescriptor> FD,
remote::TypeInfoProvider *ExternalTypeInfo) {
// Sort enum into payload and no-payload cases.
unsigned NoPayloadCases = 0;
std::vector<FieldTypeInfo> PayloadCases;
std::vector<FieldTypeInfo> Fields;
if (!TC.getBuilder().getFieldTypeRefs(TR, FD, Fields)) {
if (!TC.getBuilder().getFieldTypeRefs(TR, FD, ExternalTypeInfo, Fields)) {
Invalid = true;
return nullptr;
}
@@ -1777,7 +1782,7 @@ public:
} else {
PayloadCases.push_back(Case);
auto *CaseTR = getCaseTypeRef(Case);
auto *CaseTI = TC.getTypeInfo(CaseTR);
auto *CaseTI = TC.getTypeInfo(CaseTR, ExternalTypeInfo);
addCase(Case.Name, CaseTR, CaseTI);
}
}
@@ -1810,7 +1815,7 @@ public:
} else if (PayloadCases.size() == 1) {
// SinglePayloadEnumImplStrategy
auto *CaseTR = getCaseTypeRef(PayloadCases[0]);
auto *CaseTI = TC.getTypeInfo(CaseTR);
auto *CaseTI = TC.getTypeInfo(CaseTR, ExternalTypeInfo);
if (CaseTR == nullptr || CaseTI == nullptr) {
return nullptr;
}
@@ -1910,11 +1915,13 @@ public:
class LowerType
: public TypeRefVisitor<LowerType, const TypeInfo *> {
TypeConverter &TC;
remote::TypeInfoProvider *ExternalTypeInfo;
public:
using TypeRefVisitor<LowerType, const TypeInfo *>::visit;
LowerType(TypeConverter &TC) : TC(TC) {}
LowerType(TypeConverter &TC, remote::TypeInfoProvider *ExternalTypeInfo)
: TC(TC), ExternalTypeInfo(ExternalTypeInfo) {}
const TypeInfo *visitBuiltinTypeRef(const BuiltinTypeRef *B) {
/// The context field of a thick function is a Builtin.NativeObject.
@@ -1950,6 +1957,18 @@ public:
// Otherwise, we're out of luck.
if (FD == nullptr) {
if (ExternalTypeInfo) {
// Ask the ExternalTypeInfo. It may be a Clang-imported type.
std::string MangledName;
if (auto N = dyn_cast<NominalTypeRef>(TR))
MangledName = N->getMangledName();
else if (auto BG = dyn_cast<BoundGenericTypeRef>(TR))
MangledName = BG->getMangledName();
if (!MangledName.empty())
if (auto *imported = ExternalTypeInfo->getTypeInfo(MangledName))
return imported;
}
DEBUG_LOG(fprintf(stderr, "No TypeInfo for nominal type: "); TR->dump());
return nullptr;
}
@@ -1966,17 +1985,17 @@ public:
RecordTypeInfoBuilder builder(TC, RecordKind::Struct);
std::vector<FieldTypeInfo> Fields;
if (!TC.getBuilder().getFieldTypeRefs(TR, FD, Fields))
if (!TC.getBuilder().getFieldTypeRefs(TR, FD, ExternalTypeInfo, Fields))
return nullptr;
for (auto Field : Fields)
builder.addField(Field.Name, Field.TR);
builder.addField(Field.Name, Field.TR, ExternalTypeInfo);
return builder.build();
}
case FieldDescriptorKind::Enum:
case FieldDescriptorKind::MultiPayloadEnum: {
EnumTypeInfoBuilder builder(TC);
return builder.build(TR, FD);
return builder.build(TR, FD, ExternalTypeInfo);
}
case FieldDescriptorKind::ObjCClass:
return TC.getReferenceTypeInfo(ReferenceKind::Strong,
@@ -2002,7 +2021,7 @@ public:
const TypeInfo *visitTupleTypeRef(const TupleTypeRef *T) {
RecordTypeInfoBuilder builder(TC, RecordKind::Tuple);
for (auto Element : T->getElements())
builder.addField("", Element);
builder.addField("", Element, ExternalTypeInfo);
return builder.build();
}
@@ -2016,7 +2035,7 @@ public:
ReferenceCounting::Unknown);
case FunctionMetadataConvention::Thin:
case FunctionMetadataConvention::CFunctionPointer:
return TC.getTypeInfo(TC.getThinFunctionTypeRef());
return TC.getTypeInfo(TC.getThinFunctionTypeRef(), ExternalTypeInfo);
}
swift_runtime_unreachable("Unhandled FunctionMetadataConvention in switch.");
@@ -2026,7 +2045,7 @@ public:
visitProtocolCompositionTypeRef(const ProtocolCompositionTypeRef *PC) {
ExistentialTypeInfoBuilder builder(TC);
builder.addProtocolComposition(PC);
return builder.build();
return builder.build(ExternalTypeInfo);
}
const TypeInfo *visitMetatypeTypeRef(const MetatypeTypeRef *M) {
@@ -2037,7 +2056,7 @@ public:
case MetatypeRepresentation::Thin:
return TC.getEmptyTypeInfo();
case MetatypeRepresentation::Thick:
return TC.getTypeInfo(TC.getAnyMetatypeTypeRef());
return TC.getTypeInfo(TC.getAnyMetatypeTypeRef(), ExternalTypeInfo);
}
swift_runtime_unreachable("Unhandled MetatypeRepresentation in switch.");
@@ -2055,7 +2074,7 @@ public:
return nullptr;
}
return builder.buildMetatype();
return builder.buildMetatype(ExternalTypeInfo);
}
const TypeInfo *
@@ -2102,7 +2121,7 @@ public:
if (auto *EnumTI = dyn_cast<EnumTypeInfo>(TI)) {
if (EnumTI->isOptional() && Kind == ReferenceKind::Weak) {
auto *TI = TC.getTypeInfo(EnumTI->getCases()[0].TR);
auto *TI = TC.getTypeInfo(EnumTI->getCases()[0].TR, ExternalTypeInfo);
return rebuildStorageTypeInfo(TI, Kind);
}
}
@@ -2142,7 +2161,7 @@ public:
const TypeInfo *
visitAnyStorageTypeRef(const TypeRef *TR, ReferenceKind Kind) {
return rebuildStorageTypeInfo(TC.getTypeInfo(TR), Kind);
return rebuildStorageTypeInfo(TC.getTypeInfo(TR, ExternalTypeInfo), Kind);
}
#define REF_STORAGE(Name, name, ...) \
@@ -2170,7 +2189,9 @@ public:
}
};
const TypeInfo *TypeConverter::getTypeInfo(const TypeRef *TR) {
const TypeInfo *
TypeConverter::getTypeInfo(const TypeRef *TR,
remote::TypeInfoProvider *ExternalTypeInfo) {
// See if we already computed the result
auto found = Cache.find(TR);
if (found != Cache.end())
@@ -2184,7 +2205,7 @@ const TypeInfo *TypeConverter::getTypeInfo(const TypeRef *TR) {
}
// Compute the result and cache it
auto *TI = LowerType(*this).visit(TR);
auto *TI = LowerType(*this, ExternalTypeInfo).visit(TR);
Cache[TR] = TI;
RecursionCheck.erase(TR);
@@ -2192,8 +2213,9 @@ const TypeInfo *TypeConverter::getTypeInfo(const TypeRef *TR) {
return TI;
}
const TypeInfo *TypeConverter::getClassInstanceTypeInfo(const TypeRef *TR,
unsigned start) {
const TypeInfo *TypeConverter::getClassInstanceTypeInfo(
const TypeRef *TR, unsigned start,
remote::TypeInfoProvider *ExternalTypeInfo) {
auto FD = getBuilder().getFieldTypeInfo(TR);
if (FD == nullptr) {
DEBUG_LOG(fprintf(stderr, "No field descriptor: "); TR->dump());
@@ -2208,7 +2230,7 @@ const TypeInfo *TypeConverter::getClassInstanceTypeInfo(const TypeRef *TR,
RecordTypeInfoBuilder builder(*this, RecordKind::ClassInstance);
std::vector<FieldTypeInfo> Fields;
if (!getBuilder().getFieldTypeRefs(TR, FD, Fields))
if (!getBuilder().getFieldTypeRefs(TR, FD, ExternalTypeInfo, Fields))
return nullptr;
// Start layout from the given instance start offset. This should
@@ -2219,7 +2241,7 @@ const TypeInfo *TypeConverter::getClassInstanceTypeInfo(const TypeRef *TR,
/*bitwiseTakable=*/true);
for (auto Field : Fields)
builder.addField(Field.Name, Field.TR);
builder.addField(Field.Name, Field.TR, ExternalTypeInfo);
return builder.build();
}
case FieldDescriptorKind::Struct:

View File

@@ -901,7 +901,7 @@ public:
using TypeRefVisitor<TypeRefSubstitution, const TypeRef *>::visit;
TypeRefSubstitution(TypeRefBuilder &Builder, GenericArgumentMap Substitutions)
: Builder(Builder), Substitutions(Substitutions) {}
: Builder(Builder), Substitutions(Substitutions) {}
const TypeRef *visitBuiltinTypeRef(const BuiltinTypeRef *B) {
return B;
@@ -1081,8 +1081,8 @@ public:
}
};
const TypeRef *
TypeRef::subst(TypeRefBuilder &Builder, const GenericArgumentMap &Subs) const {
const TypeRef *TypeRef::subst(TypeRefBuilder &Builder,
const GenericArgumentMap &Subs) const {
return TypeRefSubstitution(Builder, Subs).visit(this);
}

View File

@@ -145,8 +145,7 @@ lookupTypeWitness(const std::string &MangledTypeName,
return nullptr;
}
const TypeRef * TypeRefBuilder::
lookupSuperclass(const TypeRef *TR) {
const TypeRef *TypeRefBuilder::lookupSuperclass(const TypeRef *TR) {
const auto &FD = getFieldTypeInfo(TR);
if (FD == nullptr)
return nullptr;
@@ -202,8 +201,8 @@ TypeRefBuilder::getFieldTypeInfo(const TypeRef *TR) {
}
bool TypeRefBuilder::getFieldTypeRefs(
const TypeRef *TR,
RemoteRef<FieldDescriptor> FD,
const TypeRef *TR, RemoteRef<FieldDescriptor> FD,
remote::TypeInfoProvider *ExternalTypeInfo,
std::vector<FieldTypeInfo> &Fields) {
if (FD == nullptr)
return false;

View File

@@ -471,7 +471,7 @@ swift_reflection_infoForTypeRef(SwiftReflectionContextRef ContextRef,
swift_typeref_t OpaqueTypeRef) {
auto Context = ContextRef->nativeContext;
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
auto TI = Context->getTypeInfo(TR);
auto TI = Context->getTypeInfo(TR, nullptr);
return convertTypeInfo(TI);
}
@@ -481,7 +481,7 @@ swift_reflection_childOfTypeRef(SwiftReflectionContextRef ContextRef,
unsigned Index) {
auto Context = ContextRef->nativeContext;
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
auto *TI = Context->getTypeInfo(TR);
auto *TI = Context->getTypeInfo(TR, nullptr);
return convertChild(TI, Index);
}
@@ -489,7 +489,7 @@ swift_typeinfo_t
swift_reflection_infoForMetadata(SwiftReflectionContextRef ContextRef,
uintptr_t Metadata) {
auto Context = ContextRef->nativeContext;
auto *TI = Context->getMetadataTypeInfo(Metadata);
auto *TI = Context->getMetadataTypeInfo(Metadata, nullptr);
return convertTypeInfo(TI);
}
@@ -498,7 +498,7 @@ swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
uintptr_t Metadata,
unsigned Index) {
auto Context = ContextRef->nativeContext;
auto *TI = Context->getMetadataTypeInfo(Metadata);
auto *TI = Context->getMetadataTypeInfo(Metadata, nullptr);
return convertChild(TI, Index);
}
@@ -506,7 +506,7 @@ swift_typeinfo_t
swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
uintptr_t Object) {
auto Context = ContextRef->nativeContext;
auto *TI = Context->getInstanceTypeInfo(Object);
auto *TI = Context->getInstanceTypeInfo(Object, nullptr);
return convertTypeInfo(TI);
}
@@ -515,7 +515,7 @@ swift_reflection_childOfInstance(SwiftReflectionContextRef ContextRef,
uintptr_t Object,
unsigned Index) {
auto Context = ContextRef->nativeContext;
auto *TI = Context->getInstanceTypeInfo(Object);
auto *TI = Context->getInstanceTypeInfo(Object, nullptr);
return convertChild(TI, Index);
}
@@ -529,10 +529,9 @@ int swift_reflection_projectExistential(SwiftReflectionContextRef ContextRef,
auto RemoteExistentialAddress = RemoteAddress(ExistentialAddress);
const TypeRef *InstanceTR = nullptr;
RemoteAddress RemoteStartOfInstanceData(nullptr);
auto Success = Context->projectExistential(RemoteExistentialAddress,
ExistentialTR,
&InstanceTR,
&RemoteStartOfInstanceData);
auto Success = Context->projectExistential(
RemoteExistentialAddress, ExistentialTR, &InstanceTR,
&RemoteStartOfInstanceData, nullptr);
if (Success) {
*InstanceTypeRef = reinterpret_cast<swift_typeref_t>(InstanceTR);
@@ -549,10 +548,11 @@ int swift_reflection_projectEnumValue(SwiftReflectionContextRef ContextRef,
auto Context = ContextRef->nativeContext;
auto EnumTR = reinterpret_cast<const TypeRef *>(EnumTypeRef);
auto RemoteEnumAddress = RemoteAddress(EnumAddress);
if (!Context->projectEnumValue(RemoteEnumAddress, EnumTR, CaseIndex)) {
if (!Context->projectEnumValue(RemoteEnumAddress, EnumTR, CaseIndex,
nullptr)) {
return false;
}
auto TI = Context->getTypeInfo(EnumTR);
auto TI = Context->getTypeInfo(EnumTR, nullptr);
auto *RecordTI = dyn_cast<EnumTypeInfo>(TI);
assert(RecordTI != nullptr);
if (static_cast<size_t>(*CaseIndex) >= RecordTI->getNumCases()) {
@@ -574,7 +574,7 @@ void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
swift_typeref_t OpaqueTypeRef) {
auto Context = ContextRef->nativeContext;
auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
auto TI = Context->getTypeInfo(TR);
auto TI = Context->getTypeInfo(TR, nullptr);
if (TI == nullptr) {
fprintf(stdout, "<null type info>\n");
} else {
@@ -599,7 +599,7 @@ void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
uintptr_t Metadata) {
auto Context = ContextRef->nativeContext;
auto TI = Context->getMetadataTypeInfo(Metadata);
auto TI = Context->getMetadataTypeInfo(Metadata, nullptr);
if (TI == nullptr) {
fprintf(stdout, "<null type info>\n");
} else {
@@ -610,7 +610,7 @@ void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
uintptr_t Object) {
auto Context = ContextRef->nativeContext;
auto TI = Context->getInstanceTypeInfo(Object);
auto TI = Context->getInstanceTypeInfo(Object, nullptr);
if (TI == nullptr) {
fprintf(stdout, "%s", "<null type info>\n");
} else {

View File

@@ -583,25 +583,28 @@ public:
using ReflectionContextOwner
= std::unique_ptr<void, void (*)(void*)>;
template<typename Runtime>
static std::pair<ReflectionContextOwner, TypeRefBuilder &>
makeReflectionContextForMetadataReader(
std::shared_ptr<ObjectMemoryReader> reader) {
struct ReflectionContextHolder {
ReflectionContextOwner Owner;
TypeRefBuilder &Builder;
ObjectMemoryReader &Reader;
};
template <typename Runtime>
static ReflectionContextHolder makeReflectionContextForMetadataReader(
std::shared_ptr<ObjectMemoryReader> reader) {
using ReflectionContext = ReflectionContext<Runtime>;
auto context = new ReflectionContext(reader);
auto &builder = context->getBuilder();
for (unsigned i = 0, e = reader->getImages().size(); i < e; ++i) {
context->addImage(reader->getImageStartAddress(i));
}
return {ReflectionContextOwner(context,
[](void *x){ delete (ReflectionContext*)x; }),
builder};
return {ReflectionContextOwner(
context, [](void *x) { delete (ReflectionContext *)x; }),
builder, *reader};
}
static std::pair<ReflectionContextOwner, TypeRefBuilder &>
makeReflectionContextForObjectFiles(
const std::vector<const ObjectFile *> &objectFiles) {
static ReflectionContextHolder makeReflectionContextForObjectFiles(
const std::vector<const ObjectFile *> &objectFiles) {
auto Reader = std::make_shared<ObjectMemoryReader>(objectFiles);
uint8_t pointerSize;
@@ -651,7 +654,7 @@ static int doDumpReflectionSections(ArrayRef<std::string> BinaryFilenames,
}
auto context = makeReflectionContextForObjectFiles(ObjectFiles);
auto &builder = context.second;
auto &builder = context.Builder;
switch (Action) {
case ActionType::DumpReflectionSections:
@@ -676,7 +679,7 @@ static int doDumpReflectionSections(ArrayRef<std::string> BinaryFilenames,
}
TypeRef->dump(file);
auto *TypeInfo = builder.getTypeConverter().getTypeInfo(TypeRef);
auto *TypeInfo = builder.getTypeConverter().getTypeInfo(TypeRef, nullptr);
if (TypeInfo == nullptr) {
fprintf(file, "Invalid lowering\n");
continue;