Skip to content

Commit 3d6e0f9

Browse files
authored
Merge pull request #7775 from augusto2112/full-dwarf-struct
[lldb] Add support for structs and tuple info lookup from DWARF
2 parents 999a073 + a5ee83c commit 3d6e0f9

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)