Skip to content

Commit a5ee83c

Browse files
committed
[lldb] Add support for structs and tuple info lookup from DWARF
To support embedded Swift, lldb will need to support reading type information from DWARF instead of reflection metadata (whivh it corrently relies on). This patch implements the DescriptorFinder interface by DWARFASTParserSwift, which allows it to provide the data necessary for type info reconstruction without relying on reflection metadata.
1 parent 21292fc commit a5ee83c

File tree

15 files changed

+567
-109
lines changed

15 files changed

+567
-109
lines changed

lldb/include/lldb/Target/Target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class TargetProperties : public Properties {
186186

187187
EnableSwiftCxxInterop GetEnableSwiftCxxInterop() const;
188188

189+
bool GetSwiftEnableFullDwarfDebugging() const;
190+
189191
Args GetSwiftPluginServerForPath() const;
190192

191193
bool GetSwiftAutoImportFrameworks() const;

lldb/packages/Python/lldbsuite/test/make/Makefile.rules

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,14 @@ ifeq "$(SWIFT_CXX_INTEROP)" "1"
628628
SWIFTFLAGS += -Xcc -std=c++17
629629
endif
630630

631+
#----------------------------------------------------------------------
632+
# Check if we should compile in Swift embedded mode
633+
#----------------------------------------------------------------------
634+
ifeq "$(SWIFT_EMBEDDED_MODE)" "1"
635+
SWIFTFLAGS += -gdwarf-types -enable-experimental-feature Embedded -Xfrontend -disable-objc-interop -runtime-compatibility-version none
636+
SWIFT_WMO = 1
637+
endif
638+
631639
#----------------------------------------------------------------------
632640
# Set up variables to run the Swift frontend directly.
633641
#----------------------------------------------------------------------
@@ -678,9 +686,17 @@ endif
678686

679687
VPATHSOURCES=$(patsubst %,$(VPATH)/%,$(SWIFT_SOURCES)) $(patsubst %,$(VPATH)/%,$(DYLIB_SWIFT_SOURCES))
680688

689+
# Whole module optimization and primary file directives are at direct odds with each other.
690+
# Either pick one or the other.
691+
ifeq "$(SWIFT_WMO)" "1"
692+
SWIFT_COMPILE_MODE_DIRECTIVE = "-wmo"
693+
else
694+
SWIFT_COMPILE_DIRECTIVE = "-primary-file"
695+
endif
696+
681697
%.o: %.swift $(SWIFT_BRIDGING_PCH) $(SWIFT_OBJC_HEADER)
682698
@echo "### Compiling" $<
683-
$(SWIFT_FE) -c -primary-file $< \
699+
$(SWIFT_FE) -c $(SWIFT_COMPILE_DIRECTIVE) $< \
684700
$(filter-out $(VPATH)/$<,$(filter-out $<,$(VPATHSOURCES))) \
685701
$(SWIFT_FEFLAGS) $(SWIFT_HFLAGS) $(PARSE_AS_LIBRARY) \
686702
-module-name $(MODULENAME) -emit-module-path \

lldb/source/Plugins/LanguageRuntime/Swift/ReflectionContext.cpp

Lines changed: 94 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,60 @@
1515
#include "lldb/Utility/LLDBLog.h"
1616
#include "lldb/Utility/Log.h"
1717
#include "swift/Demangling/Demangle.h"
18+
#include "swift/RemoteInspection/DescriptorFinder.h"
1819

1920
using namespace lldb;
2021
using namespace lldb_private;
2122

2223
namespace {
2324

25+
/// The descriptor finder needs to be an instance variable of the
26+
/// TypeRefBuilder, but we would still want to swap out the descriptor finder,
27+
/// as they are tied to each type system typeref's symbol file. This class's
28+
/// only purpose is to allow this swapping.
29+
struct DescriptorFinderForwarder : public swift::reflection::DescriptorFinder {
30+
DescriptorFinderForwarder() = default;
31+
~DescriptorFinderForwarder() override = default;
32+
33+
std::unique_ptr<swift::reflection::BuiltinTypeDescriptorBase>
34+
getBuiltinTypeDescriptor(const swift::reflection::TypeRef *TR) override {
35+
if (m_descriptor_finder)
36+
return m_descriptor_finder->getBuiltinTypeDescriptor(TR);
37+
return nullptr;
38+
}
39+
40+
std::unique_ptr<swift::reflection::FieldDescriptorBase>
41+
getFieldDescriptor(const swift::reflection::TypeRef *TR) override {
42+
if (m_descriptor_finder)
43+
return m_descriptor_finder->getFieldDescriptor(TR);
44+
return nullptr;
45+
}
46+
47+
void SetExternalDescriptorFinder(
48+
swift::reflection::DescriptorFinder *desciptor_finder) {
49+
m_descriptor_finder = desciptor_finder;
50+
}
51+
52+
void ClearExternalDescriptorFinder() { m_descriptor_finder = nullptr; }
53+
54+
private:
55+
swift::reflection::DescriptorFinder *m_descriptor_finder = nullptr;
56+
};
57+
2458
/// An implementation of the generic ReflectionContextInterface that
2559
/// is templatized on target pointer width and specialized to either
2660
/// 32-bit or 64-bit pointers, with and without ObjC interoperability.
2761
template <typename ReflectionContext>
28-
class TargetReflectionContext
29-
: public ReflectionContextInterface {
62+
class TargetReflectionContext : public ReflectionContextInterface {
63+
DescriptorFinderForwarder m_forwader;
3064
ReflectionContext m_reflection_ctx;
3165
swift::reflection::TypeConverter m_type_converter;
3266

3367
public:
3468
TargetReflectionContext(
3569
std::shared_ptr<swift::reflection::MemoryReader> reader,
3670
SwiftMetadataCache *swift_metadata_cache)
37-
: m_reflection_ctx(reader, swift_metadata_cache),
71+
: m_reflection_ctx(reader, swift_metadata_cache, &m_forwader),
3872
m_type_converter(m_reflection_ctx.getBuilder()) {}
3973

4074
llvm::Optional<uint32_t> AddImage(
@@ -59,20 +93,31 @@ class TargetReflectionContext
5993
likely_module_names);
6094
}
6195

62-
const swift::reflection::TypeRef *
63-
GetTypeRefOrNull(StringRef mangled_type_name) override {
96+
const swift::reflection::TypeRef *GetTypeRefOrNull(
97+
StringRef mangled_type_name,
98+
swift::reflection::DescriptorFinder *descriptor_finder) override {
6499
swift::Demangle::Demangler dem;
65100
swift::Demangle::NodePointer node = dem.demangleSymbol(mangled_type_name);
66-
const swift::reflection::TypeRef *type_ref = GetTypeRefOrNull(dem, node);
101+
const swift::reflection::TypeRef *type_ref =
102+
GetTypeRefOrNull(dem, node, descriptor_finder);
67103
if (!type_ref)
68104
LLDB_LOG(GetLog(LLDBLog::Types), "Could not find typeref for type: {0}",
69105
mangled_type_name);
70106
return type_ref;
71107
}
72108

73-
virtual const swift::reflection::TypeRef *
74-
GetTypeRefOrNull(swift::Demangle::Demangler &dem,
75-
swift::Demangle::NodePointer node) override {
109+
/// Sets the descriptor finder, and on scope exit clears it out.
110+
auto SetDescriptorFinderAndClearOnExit(
111+
swift::reflection::DescriptorFinder *descriptor_finder) {
112+
m_forwader.SetExternalDescriptorFinder(descriptor_finder);
113+
return llvm::make_scope_exit(
114+
[&]() { m_forwader.ClearExternalDescriptorFinder(); });
115+
}
116+
117+
const swift::reflection::TypeRef *GetTypeRefOrNull(
118+
swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node,
119+
swift::reflection::DescriptorFinder *descriptor_finder) override {
120+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
76121
auto type_ref_or_err =
77122
swift::Demangle::decodeMangledType(m_reflection_ctx.getBuilder(), node);
78123
if (type_ref_or_err.isError()) {
@@ -84,17 +129,21 @@ class TargetReflectionContext
84129
return type_ref_or_err.getType();
85130
}
86131

87-
const swift::reflection::TypeInfo *
88-
GetClassInstanceTypeInfo(const swift::reflection::TypeRef *type_ref,
89-
swift::remote::TypeInfoProvider *provider) override {
132+
const swift::reflection::TypeInfo *GetClassInstanceTypeInfo(
133+
const swift::reflection::TypeRef *type_ref,
134+
swift::remote::TypeInfoProvider *provider,
135+
swift::reflection::DescriptorFinder *descriptor_finder) override {
136+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
90137
if (!type_ref)
91138
return nullptr;
92139
return m_type_converter.getClassInstanceTypeInfo(type_ref, 0, provider);
93140
}
94141

95142
const swift::reflection::TypeInfo *
96143
GetTypeInfo(const swift::reflection::TypeRef *type_ref,
97-
swift::remote::TypeInfoProvider *provider) override {
144+
swift::remote::TypeInfoProvider *provider,
145+
swift::reflection::DescriptorFinder *descriptor_finder) override {
146+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
98147
if (!type_ref)
99148
return nullptr;
100149

@@ -128,24 +177,30 @@ class TargetReflectionContext
128177
return type_info;
129178
}
130179

131-
const swift::reflection::TypeInfo *
132-
GetTypeInfoFromInstance(lldb::addr_t instance,
133-
swift::remote::TypeInfoProvider *provider) override {
180+
const swift::reflection::TypeInfo *GetTypeInfoFromInstance(
181+
lldb::addr_t instance, swift::remote::TypeInfoProvider *provider,
182+
swift::reflection::DescriptorFinder *descriptor_finder) override {
183+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
134184
return m_reflection_ctx.getInstanceTypeInfo(instance, provider);
135185
}
136186

137187
swift::reflection::MemoryReader &GetReader() override {
138188
return m_reflection_ctx.getReader();
139189
}
140190

141-
const swift::reflection::TypeRef *
142-
LookupSuperclass(const swift::reflection::TypeRef *tr) override {
191+
const swift::reflection::TypeRef *LookupSuperclass(
192+
const swift::reflection::TypeRef *tr,
193+
swift::reflection::DescriptorFinder *descriptor_finder) override {
194+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
143195
return m_reflection_ctx.getBuilder().lookupSuperclass(tr);
144196
}
145197

146-
bool ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
147-
lldb::addr_t pointer,
148-
std::function<bool(SuperClassType)> fn) override {
198+
bool
199+
ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
200+
swift::reflection::DescriptorFinder *descriptor_finder,
201+
lldb::addr_t pointer,
202+
std::function<bool(SuperClassType)> fn) override {
203+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
149204
// Guard against faulty self-referential metadata.
150205
unsigned limit = 256;
151206
auto md_ptr = m_reflection_ctx.readMetadataFromInstance(pointer);
@@ -175,10 +230,12 @@ class TargetReflectionContext
175230
return false;
176231
}
177232

178-
llvm::Optional<int32_t>
179-
ProjectEnumValue(swift::remote::RemoteAddress enum_addr,
180-
const swift::reflection::TypeRef *enum_type_ref,
181-
swift::remote::TypeInfoProvider *provider) override {
233+
llvm::Optional<int32_t> ProjectEnumValue(
234+
swift::remote::RemoteAddress enum_addr,
235+
const swift::reflection::TypeRef *enum_type_ref,
236+
swift::remote::TypeInfoProvider *provider,
237+
swift::reflection::DescriptorFinder *descriptor_finder) override {
238+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
182239
int32_t case_idx;
183240
if (m_reflection_ctx.projectEnumValue(enum_addr, enum_type_ref, &case_idx,
184241
provider))
@@ -190,21 +247,27 @@ class TargetReflectionContext
190247
swift::reflection::RemoteAddress>>
191248
ProjectExistentialAndUnwrapClass(
192249
swift::reflection::RemoteAddress existential_address,
193-
const swift::reflection::TypeRef &existential_tr) override {
250+
const swift::reflection::TypeRef &existential_tr,
251+
swift::reflection::DescriptorFinder *descriptor_finder) override {
252+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
194253
return m_reflection_ctx.projectExistentialAndUnwrapClass(
195254
existential_address, existential_tr);
196255
}
197256

198257
const swift::reflection::TypeRef *
199258
ReadTypeFromMetadata(lldb::addr_t metadata_address,
259+
swift::reflection::DescriptorFinder *descriptor_finder,
200260
bool skip_artificial_subclasses) override {
261+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
201262
return m_reflection_ctx.readTypeFromMetadata(metadata_address,
202263
skip_artificial_subclasses);
203264
}
204265

205266
const swift::reflection::TypeRef *
206267
ReadTypeFromInstance(lldb::addr_t instance_address,
268+
swift::reflection::DescriptorFinder *descriptor_finder,
207269
bool skip_artificial_subclasses) override {
270+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
208271
auto metadata_address =
209272
m_reflection_ctx.readMetadataFromInstance(instance_address);
210273
if (!metadata_address) {
@@ -226,12 +289,14 @@ class TargetReflectionContext
226289

227290
const swift::reflection::TypeRef *ApplySubstitutions(
228291
const swift::reflection::TypeRef *type_ref,
229-
swift::reflection::GenericArgumentMap substitutions) override{
292+
swift::reflection::GenericArgumentMap substitutions,
293+
swift::reflection::DescriptorFinder *descriptor_finder) override {
294+
auto on_exit = SetDescriptorFinderAndClearOnExit(descriptor_finder);
230295
return type_ref->subst(m_reflection_ctx.getBuilder(), substitutions);
231296
}
232297

233-
swift::remote::RemoteAbsolutePointer StripSignedPointer(
234-
swift::remote::RemoteAbsolutePointer pointer) override {
298+
swift::remote::RemoteAbsolutePointer
299+
StripSignedPointer(swift::remote::RemoteAbsolutePointer pointer) override {
235300
return m_reflection_ctx.stripSignedPointer(pointer);
236301
}
237302
};

lldb/source/Plugins/LanguageRuntime/Swift/ReflectionContextInterface.h

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace Demangle {
3030
class Demangler;
3131
} // namespace Demangle
3232
namespace reflection {
33+
struct DescriptorFinder;
3334
class RecordTypeInfo;
3435
class TypeInfo;
3536
} // namespace reflection
@@ -79,47 +80,56 @@ class ReflectionContextInterface {
7980
ReadELF(swift::remote::RemoteAddress ImageStart,
8081
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
8182
llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
82-
virtual const swift::reflection::TypeRef *
83-
GetTypeRefOrNull(llvm::StringRef mangled_type_name) = 0;
84-
virtual const swift::reflection::TypeRef *
85-
GetTypeRefOrNull(swift::Demangle::Demangler &dem,
86-
swift::Demangle::NodePointer node) = 0;
87-
virtual const swift::reflection::TypeInfo *
88-
GetClassInstanceTypeInfo(const swift::reflection::TypeRef *type_ref,
89-
swift::remote::TypeInfoProvider *provider) = 0;
90-
virtual const swift::reflection::TypeInfo *
91-
GetTypeInfo(const swift::reflection::TypeRef *type_ref,
92-
swift::remote::TypeInfoProvider *provider) = 0;
93-
virtual const swift::reflection::TypeInfo *
94-
GetTypeInfoFromInstance(lldb::addr_t instance,
95-
swift::remote::TypeInfoProvider *provider) = 0;
83+
virtual const swift::reflection::TypeRef *GetTypeRefOrNull(
84+
llvm::StringRef mangled_type_name,
85+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
86+
virtual const swift::reflection::TypeRef *GetTypeRefOrNull(
87+
swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node,
88+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
89+
virtual const swift::reflection::TypeInfo *GetClassInstanceTypeInfo(
90+
const swift::reflection::TypeRef *type_ref,
91+
swift::remote::TypeInfoProvider *provider,
92+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
93+
virtual const swift::reflection::TypeInfo *GetTypeInfo(
94+
const swift::reflection::TypeRef *type_ref,
95+
swift::remote::TypeInfoProvider *provider,
96+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
97+
virtual const swift::reflection::TypeInfo *GetTypeInfoFromInstance(
98+
lldb::addr_t instance, swift::remote::TypeInfoProvider *provider,
99+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
96100
virtual swift::remote::MemoryReader &GetReader() = 0;
97-
virtual const swift::reflection::TypeRef *
98-
LookupSuperclass(const swift::reflection::TypeRef *tr) = 0;
99-
virtual bool
100-
ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
101-
lldb::addr_t pointer,
102-
std::function<bool(SuperClassType)> fn) = 0;
101+
virtual const swift::reflection::TypeRef *LookupSuperclass(
102+
const swift::reflection::TypeRef *tr,
103+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
104+
virtual bool ForEachSuperClassType(
105+
swift::remote::TypeInfoProvider *tip,
106+
swift::reflection::DescriptorFinder *descriptor_finder,
107+
lldb::addr_t pointer, std::function<bool(SuperClassType)> fn) = 0;
103108
virtual llvm::Optional<std::pair<const swift::reflection::TypeRef *,
104109
swift::remote::RemoteAddress>>
105110
ProjectExistentialAndUnwrapClass(
106111
swift::remote::RemoteAddress existential_addess,
107-
const swift::reflection::TypeRef &existential_tr) = 0;
108-
virtual llvm::Optional<int32_t>
109-
ProjectEnumValue(swift::remote::RemoteAddress enum_addr,
110-
const swift::reflection::TypeRef *enum_type_ref,
111-
swift::remote::TypeInfoProvider *provider) = 0;
112-
virtual const swift::reflection::TypeRef *
113-
ReadTypeFromMetadata(lldb::addr_t metadata_address,
114-
bool skip_artificial_subclasses = false) = 0;
115-
virtual const swift::reflection::TypeRef *
116-
ReadTypeFromInstance(lldb::addr_t instance_address,
117-
bool skip_artificial_subclasses = false) = 0;
112+
const swift::reflection::TypeRef &existential_tr,
113+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
114+
virtual llvm::Optional<int32_t> ProjectEnumValue(
115+
swift::remote::RemoteAddress enum_addr,
116+
const swift::reflection::TypeRef *enum_type_ref,
117+
swift::remote::TypeInfoProvider *provider,
118+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
119+
virtual const swift::reflection::TypeRef *ReadTypeFromMetadata(
120+
lldb::addr_t metadata_address,
121+
swift::reflection::DescriptorFinder *descriptor_finder,
122+
bool skip_artificial_subclasses = false) = 0;
123+
virtual const swift::reflection::TypeRef *ReadTypeFromInstance(
124+
lldb::addr_t instance_address,
125+
swift::reflection::DescriptorFinder *descriptor_finder,
126+
bool skip_artificial_subclasses = false) = 0;
118127
virtual llvm::Optional<bool> IsValueInlinedInExistentialContainer(
119128
swift::remote::RemoteAddress existential_address) = 0;
120-
virtual const swift::reflection::TypeRef *
121-
ApplySubstitutions(const swift::reflection::TypeRef *type_ref,
122-
swift::reflection::GenericArgumentMap substitutions) = 0;
129+
virtual const swift::reflection::TypeRef *ApplySubstitutions(
130+
const swift::reflection::TypeRef *type_ref,
131+
swift::reflection::GenericArgumentMap substitutions,
132+
swift::reflection::DescriptorFinder *descriptor_finder) = 0;
123133
virtual swift::remote::RemoteAbsolutePointer
124134
StripSignedPointer(swift::remote::RemoteAbsolutePointer pointer) = 0;
125135
};

0 commit comments

Comments
 (0)