Skip to content

Commit 4247b60

Browse files
Merge pull request #33417 from adrian-prantl/55412920
Add a callback to swift::reflection::MemoryReader that allows LLDB to…
2 parents db6e3af + 56b2e90 commit 4247b60

File tree

14 files changed

+284
-148
lines changed

14 files changed

+284
-148
lines changed

include/swift/Demangling/TypeDecoder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,8 @@ class TypeDecoder {
349349

350350
BuilderType &Builder;
351351

352-
public:
353-
explicit TypeDecoder(BuilderType &Builder)
354-
: Builder(Builder) {}
352+
public:
353+
explicit TypeDecoder(BuilderType &Builder) : Builder(Builder) {}
355354

356355
/// Given a demangle tree, attempt to turn it into a type.
357356
TypeLookupErrorOr<BuiltType> decodeMangledType(NodePointer Node) {

include/swift/Reflection/ReflectionContext.h

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,9 @@ class ReflectionContext
680680

681681
/// Return a description of the layout of a class instance with the given
682682
/// metadata as its isa pointer.
683-
const TypeInfo *getMetadataTypeInfo(StoredPointer MetadataAddress) {
683+
const TypeInfo *
684+
getMetadataTypeInfo(StoredPointer MetadataAddress,
685+
remote::TypeInfoProvider *ExternalTypeInfo) {
684686
// See if we cached the layout already
685687
auto found = Cache.find(MetadataAddress);
686688
if (found != Cache.end())
@@ -702,7 +704,7 @@ class ReflectionContext
702704

703705
// Perform layout
704706
if (start)
705-
TI = TC.getClassInstanceTypeInfo(TR, *start);
707+
TI = TC.getClassInstanceTypeInfo(TR, *start, ExternalTypeInfo);
706708

707709
break;
708710
}
@@ -718,7 +720,9 @@ class ReflectionContext
718720

719721
/// Return a description of the layout of a class instance with the given
720722
/// metadata as its isa pointer.
721-
const TypeInfo *getInstanceTypeInfo(StoredPointer ObjectAddress) {
723+
const TypeInfo *
724+
getInstanceTypeInfo(StoredPointer ObjectAddress,
725+
remote::TypeInfoProvider *ExternalTypeInfo) {
722726
auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
723727
if (!MetadataAddress)
724728
return nullptr;
@@ -729,7 +733,7 @@ class ReflectionContext
729733

730734
switch (*kind) {
731735
case MetadataKind::Class:
732-
return getMetadataTypeInfo(*MetadataAddress);
736+
return getMetadataTypeInfo(*MetadataAddress, ExternalTypeInfo);
733737

734738
case MetadataKind::HeapLocalVariable: {
735739
auto CDAddr = this->readCaptureDescriptorFromMetadata(*MetadataAddress);
@@ -751,7 +755,7 @@ class ReflectionContext
751755

752756
auto Info = getBuilder().getClosureContextInfo(CD);
753757

754-
return getClosureContextInfo(ObjectAddress, Info);
758+
return getClosureContextInfo(ObjectAddress, Info, ExternalTypeInfo);
755759
}
756760

757761
case MetadataKind::HeapGenericLocalVariable: {
@@ -760,7 +764,8 @@ class ReflectionContext
760764
if (auto Meta = readMetadata(*MetadataAddress)) {
761765
auto GenericHeapMeta =
762766
cast<TargetGenericBoxHeapMetadata<Runtime>>(Meta.getLocalBuffer());
763-
return getMetadataTypeInfo(GenericHeapMeta->BoxedType);
767+
return getMetadataTypeInfo(GenericHeapMeta->BoxedType,
768+
ExternalTypeInfo);
764769
}
765770
return nullptr;
766771
}
@@ -774,15 +779,15 @@ class ReflectionContext
774779
}
775780
}
776781

777-
bool
778-
projectExistential(RemoteAddress ExistentialAddress,
779-
const TypeRef *ExistentialTR,
780-
const TypeRef **OutInstanceTR,
781-
RemoteAddress *OutInstanceAddress) {
782+
bool projectExistential(RemoteAddress ExistentialAddress,
783+
const TypeRef *ExistentialTR,
784+
const TypeRef **OutInstanceTR,
785+
RemoteAddress *OutInstanceAddress,
786+
remote::TypeInfoProvider *ExternalTypeInfo) {
782787
if (ExistentialTR == nullptr)
783788
return false;
784789

785-
auto ExistentialTI = getTypeInfo(ExistentialTR);
790+
auto ExistentialTI = getTypeInfo(ExistentialTR, ExternalTypeInfo);
786791
if (ExistentialTI == nullptr)
787792
return false;
788793

@@ -846,14 +851,14 @@ class ReflectionContext
846851
/// Returns true if the enum case could be successfully determined. In
847852
/// particular, note that this code may return false for valid in-memory data
848853
/// if the compiler used a strategy we do not yet understand.
849-
bool projectEnumValue(RemoteAddress EnumAddress,
850-
const TypeRef *EnumTR,
851-
int *CaseIndex) {
854+
bool projectEnumValue(RemoteAddress EnumAddress, const TypeRef *EnumTR,
855+
int *CaseIndex,
856+
remote::TypeInfoProvider *ExternalTypeInfo) {
852857
// Get the TypeInfo and sanity-check it
853858
if (EnumTR == nullptr) {
854859
return false;
855860
}
856-
auto TI = getTypeInfo(EnumTR);
861+
auto TI = getTypeInfo(EnumTR, ExternalTypeInfo);
857862
if (TI == nullptr) {
858863
return false;
859864
}
@@ -865,11 +870,12 @@ class ReflectionContext
865870
}
866871

867872
/// Return a description of the layout of a value with the given type.
868-
const TypeInfo *getTypeInfo(const TypeRef *TR) {
873+
const TypeInfo *getTypeInfo(const TypeRef *TR,
874+
remote::TypeInfoProvider *ExternalTypeInfo) {
869875
if (TR == nullptr) {
870876
return nullptr;
871877
} else {
872-
return getBuilder().getTypeConverter().getTypeInfo(TR);
878+
return getBuilder().getTypeConverter().getTypeInfo(TR, ExternalTypeInfo);
873879
}
874880
}
875881

@@ -1160,8 +1166,9 @@ class ReflectionContext
11601166
}
11611167

11621168
private:
1163-
const TypeInfo *getClosureContextInfo(StoredPointer Context,
1164-
const ClosureContextInfo &Info) {
1169+
const TypeInfo *
1170+
getClosureContextInfo(StoredPointer Context, const ClosureContextInfo &Info,
1171+
remote::TypeInfoProvider *ExternalTypeInfo) {
11651172
RecordTypeInfoBuilder Builder(getBuilder().getTypeConverter(),
11661173
RecordKind::ClosureContext);
11671174

@@ -1219,7 +1226,7 @@ class ReflectionContext
12191226
SubstCaptureTR = OrigCaptureTR;
12201227

12211228
if (SubstCaptureTR != nullptr) {
1222-
Builder.addField("", SubstCaptureTR);
1229+
Builder.addField("", SubstCaptureTR, ExternalTypeInfo);
12231230
if (Builder.isInvalid())
12241231
return nullptr;
12251232

include/swift/Reflection/TypeLowering.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/ADT/DenseSet.h"
2323
#include "llvm/Support/Casting.h"
2424
#include "swift/Remote/MetadataReader.h"
25+
#include "swift/Remote/TypeInfoProvider.h"
2526

2627
#include <memory>
2728

@@ -316,7 +317,8 @@ class ReferenceTypeInfo : public TypeInfo {
316317
class TypeConverter {
317318
TypeRefBuilder &Builder;
318319
std::vector<std::unique_ptr<const TypeInfo>> Pool;
319-
llvm::DenseMap<const TypeRef *, const TypeInfo *> Cache;
320+
llvm::DenseMap<std::pair<const TypeRef *, remote::TypeInfoProvider *>,
321+
const TypeInfo *> Cache;
320322
llvm::DenseSet<const TypeRef *> RecursionCheck;
321323
llvm::DenseMap<std::pair<unsigned, unsigned>,
322324
const ReferenceTypeInfo *> ReferenceCache;
@@ -347,14 +349,16 @@ class TypeConverter {
347349
///
348350
/// The type must either be concrete, or at least fixed-size, as
349351
/// determined by the isFixedSize() predicate.
350-
const TypeInfo *getTypeInfo(const TypeRef *TR);
352+
const TypeInfo *getTypeInfo(const TypeRef *TR,
353+
remote::TypeInfoProvider *externalInfo);
351354

352355
/// Returns layout information for an instance of the given
353356
/// class.
354357
///
355358
/// Not cached.
356-
const TypeInfo *getClassInstanceTypeInfo(const TypeRef *TR,
357-
unsigned start);
359+
const TypeInfo *
360+
getClassInstanceTypeInfo(const TypeRef *TR, unsigned start,
361+
remote::TypeInfoProvider *ExternalTypeInfo);
358362

359363
private:
360364
friend class swift::reflection::LowerType;
@@ -415,7 +419,8 @@ class RecordTypeInfoBuilder {
415419
bool bitwiseTakable);
416420

417421
// Add a field of a record type, such as a struct.
418-
void addField(const std::string &Name, const TypeRef *TR);
422+
void addField(const std::string &Name, const TypeRef *TR,
423+
remote::TypeInfoProvider *ExternalTypeInfo);
419424

420425
const RecordTypeInfo *build();
421426

include/swift/Reflection/TypeRef.h

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ class alignas(void *) TypeRef {
156156
bool isConcrete() const;
157157
bool isConcreteAfterSubstitutions(const GenericArgumentMap &Subs) const;
158158

159-
const TypeRef *
160-
subst(TypeRefBuilder &Builder, const GenericArgumentMap &Subs) const;
159+
const TypeRef *subst(TypeRefBuilder &Builder,
160+
const GenericArgumentMap &Subs) const;
161161

162162
llvm::Optional<GenericArgumentMap> getSubstMap() const;
163163

@@ -301,27 +301,48 @@ class BoundGenericTypeRef final : public TypeRef, public NominalTypeTrait {
301301
};
302302

303303
class TupleTypeRef final : public TypeRef {
304+
protected:
304305
std::vector<const TypeRef *> Elements;
306+
std::string Labels;
305307

306-
static TypeRefID Profile(const std::vector<const TypeRef *> &Elements) {
308+
static TypeRefID Profile(const std::vector<const TypeRef *> &Elements,
309+
const std::string &Labels) {
307310
TypeRefID ID;
308311
for (auto Element : Elements)
309312
ID.addPointer(Element);
313+
ID.addString(Labels);
310314
return ID;
311315
}
312316

313317
public:
314-
TupleTypeRef(std::vector<const TypeRef *> Elements)
315-
: TypeRef(TypeRefKind::Tuple), Elements(std::move(Elements)) {}
318+
TupleTypeRef(std::vector<const TypeRef *> Elements, std::string &&Labels)
319+
: TypeRef(TypeRefKind::Tuple), Elements(std::move(Elements)),
320+
Labels(Labels) {}
316321

317322
template <typename Allocator>
318323
static const TupleTypeRef *create(Allocator &A,
319-
std::vector<const TypeRef *> Elements) {
320-
FIND_OR_CREATE_TYPEREF(A, TupleTypeRef, Elements);
321-
}
322-
323-
const std::vector<const TypeRef *> &getElements() const {
324-
return Elements;
324+
std::vector<const TypeRef *> Elements,
325+
std::string &&Labels) {
326+
FIND_OR_CREATE_TYPEREF(A, TupleTypeRef, Elements, Labels);
327+
}
328+
329+
const std::vector<const TypeRef *> &getElements() const { return Elements; };
330+
const std::string &getLabelString() const { return Labels; };
331+
std::vector<llvm::StringRef> getLabels() const {
332+
std::vector<llvm::StringRef> Vec;
333+
std::string::size_type End, Start = 0;
334+
while (true) {
335+
End = Labels.find(' ', Start);
336+
if (End == std::string::npos)
337+
break;
338+
Vec.push_back(llvm::StringRef(Labels.data() + Start, End - Start));
339+
Start = End + 1;
340+
}
341+
// A canonicalized TypeRef has an empty label string.
342+
// Pad the vector with empty labels.
343+
for (unsigned N = Vec.size(); N < Elements.size(); ++N)
344+
Vec.push_back({});
345+
return Vec;
325346
};
326347

327348
static bool classof(const TypeRef *TR) {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,7 @@ class TypeRefBuilder {
405405

406406
const TupleTypeRef *createTupleType(llvm::ArrayRef<const TypeRef *> elements,
407407
std::string &&labels) {
408-
// FIXME: Add uniqueness checks in TupleTypeRef::Profile and
409-
// unittests/Reflection/TypeRef.cpp if using labels for identity.
410-
return TupleTypeRef::create(*this, elements);
408+
return TupleTypeRef::create(*this, elements, std::move(labels));
411409
}
412410

413411
const FunctionTypeRef *createFunctionType(
@@ -634,16 +632,14 @@ class TypeRefBuilder {
634632
const std::string &Member,
635633
StringRef Protocol);
636634

637-
const TypeRef *
638-
lookupSuperclass(const TypeRef *TR);
635+
const TypeRef *lookupSuperclass(const TypeRef *TR);
639636

640637
/// Load unsubstituted field types for a nominal type.
641-
RemoteRef<FieldDescriptor>
642-
getFieldTypeInfo(const TypeRef *TR);
638+
RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
643639

644640
/// Get the parsed and substituted field types for a nominal type.
645-
bool getFieldTypeRefs(const TypeRef *TR,
646-
RemoteRef<FieldDescriptor> FD,
641+
bool getFieldTypeRefs(const TypeRef *TR, RemoteRef<FieldDescriptor> FD,
642+
remote::TypeInfoProvider *ExternalTypeInfo,
647643
std::vector<FieldTypeInfo> &Fields);
648644

649645
/// Get the primitive type lowering for a builtin type.

include/swift/Remote/MemoryReader.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ namespace remote {
3737
class MemoryReader {
3838
public:
3939
/// A convenient name for the return type from readBytes.
40-
using ReadBytesResult = std::unique_ptr<const void, std::function<void(const void *)>>;
40+
using ReadBytesResult =
41+
std::unique_ptr<const void, std::function<void(const void *)>>;
4142

4243
virtual bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
4344
void *outBuffer) = 0;
@@ -152,9 +153,8 @@ class MemoryReader {
152153

153154
return resolvePointer(address, pointerData);
154155
}
155-
156156

157-
// Parse extra inhabitants stored in a pointer.
157+
// Parse extra inhabitants stored in a pointer.
158158
// Sets *extraInhabitant to -1 if the pointer at this address
159159
// is actually a valid pointer.
160160
// Otherwise, it sets *extraInhabitant to the inhabitant
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===--- TypeInfoProvider.h - Abstract access to type info ------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file declares an abstract interface for reading type layout info.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_REMOTE_TYPEINFOPROVIDER_H
18+
#define SWIFT_REMOTE_TYPEINFOPROVIDER_H
19+
20+
namespace swift {
21+
namespace reflection {
22+
class TypeInfo;
23+
}
24+
namespace remote {
25+
26+
/// An abstract interface for providing external type layout information.
27+
struct TypeInfoProvider {
28+
virtual ~TypeInfoProvider() = default;
29+
30+
/// Attempt to read type information about (Clang)imported types that are not
31+
/// represented in the metadata. LLDB can read this information from debug
32+
/// info, for example.
33+
virtual const reflection::TypeInfo *
34+
getTypeInfo(llvm::StringRef mangledName) = 0;
35+
};
36+
37+
} // namespace remote
38+
} // namespace swift
39+
#endif

lib/AST/ASTDemangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ Type ASTBuilder::createNominalType(GenericTypeDecl *decl, Type parent) {
144144
return Type();
145145

146146
// If the declaration is generic, fail.
147-
if (nominalDecl->getGenericParams())
147+
if (auto list = nominalDecl->getGenericParams())
148148
return Type();
149149

150150
// Imported types can be renamed to be members of other (non-generic)

0 commit comments

Comments
 (0)